飞镖中的异步可迭代映射

时间:2016-06-24 14:21:10

标签: dart

我可以使用异步映射功能映射一些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);
}

4 个答案:

答案 0 :(得分:4)

表达式(i) async => await foo(i)仍然会返回未来。您可以使用Future.wait(mappedList)等待所有创建的期货完成。

答案 1 :(得分:2)

您的误解是异步函数返回Future,而不是值。 await不会将异步转换为同步。

var mappedList = list.map(
  (i) async => await foo(i) // Returns a Future, not an int
);

您正在打印的是(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);
  }
}

在Dartpad上:https://dartpad.dartlang.org/151949be67c0cdc0c54742113c98b291

有些注意事项:

List.map()返回懒惰Iterable (不是List),这意味着在Iterable之前不会调用映射函数迭代完毕。

第一个循环在打印之前等待每个Future完成并继续前进到Iterable中的下一个项目,下一个项目的映射函数(因此foo())是在打印每个值后调用,因此以1秒的间隔打印值。

第二个循环立即遍历Iterable,设置一个打印函数,在每个Future完成后执行。一次调用5个函数foo()的实例,这些实例都在大约1秒后返回,然后打印所有5个值。

答案 2 :(得分:1)

添加某种类型将解释发生了什么:

controller: ['DataService', function AppController('DataService')

答案 3 :(得分:1)

在我的情况下,其他答案并没有真正起作用,最终像这样使用rxdart的{​​{1}}:

asyncMap