我可以使用异步映射功能映射一些Iterable吗?也许这是一个错误,该代码会隐式打印_Future列表,而不是在1或5秒后显示整数吗?
import 'dart:async';
Future<int> foo(int i) {
var c = new Completer();
new Timer(new Duration(seconds: 1), () => c.complete(i));
return c.future;
}
main() {
var list = [1,2,3,4,5];
var mappedList = list.map((i) async => await foo(i));
print(mappedList);
}
Run Code Online (Sandbox Code Playgroud)
Fox*_*x32 10
该表达式(i) async => await foo(i)仍返回未来。您可以Future.wait(mappedList)用来等待所有创建的期货完成。
其他答案在我的情况下并没有真正起作用,最终使用rxdart的asyncMap是这样的:
Observable.fromIterable(list)
.asyncMap((item) => foo(item))
.toList();
Run Code Online (Sandbox Code Playgroud)
编辑:Observable自rxdart 0.23.0以来,类已停止使用,您可以像这样使用Streams:
Stream
.fromIterable(list)
.asyncMap((item) => foo(item))
.toList();
Run Code Online (Sandbox Code Playgroud)
添加一些类型将解释发生了什么:
main() async {
var list = [1,2,3,4,5];
Iterable<Future<int>> mappedList = list.map((i) async => await foo(i));
print(mappedList); // you print an Iterable of Future
// to get the list of int you have to do the following
Future<List<int>> futureList = Future.wait(mappedList);
List<int> result = await futureList;
print(result);
}
Run Code Online (Sandbox Code Playgroud)
有了今天的 Dart,就没有问题了。忘记了map,直接构建你的列表:
final list = [for (final item in items) await buildAsync(item)];
Run Code Online (Sandbox Code Playgroud)
您的误解是异步函数返回一个Future,而不是一个值。await不会将异步转换为同步。
var mappedList = list.map(
(i) async => await foo(i) // Returns a Future, not an int
);
Run Code Online (Sandbox Code Playgroud)
您正在打印的是所返回的期货(i) async => await foo(i)。
这些期货在其中的期货链完成时完成。当计时器触发时:foo()完成,然后完成,然后执行await foo(i)映射功能。
与之比较:
main() async {
List<int> list = [1,2,3,4,5];
Iterable<Future<int>> mapped;
// Prints ints 1 second apart
mapped = list.map((i) => foo(i));
for(Future<int> f in mapped) {
print(await f);
}
// Prints ints all at once, after 1 second wait
mapped = list.map((i) => foo(i));
for(Future<int> f in mapped) {
f.then(print);
}
}
Run Code Online (Sandbox Code Playgroud)
在Dartpad上:https://dartpad.dartlang.org/151949be67c0cdc0c54742113c98b291
注意事项:
List.map()返回一个懒惰Iterable(不是a List),这意味着直到Iterable迭代通过时才调用映射函数。
第一个循环等待每个Future完成,然后再打印并移至中的下一个项目,在打印每个值后将调用Iterable下一个项目的映射函数(因此foo()),因此将以1秒的间隔打印值。
第二个循环Iterable立即循环遍历,设置打印功能以在每次Future完成后执行。一次调用函数foo()的5个实例,它们全部在大约1秒钟后返回,然后打印所有5个值。
| 归档时间: |
|
| 查看次数: |
2952 次 |
| 最近记录: |