[dart]如何在Future <void>函数中等待map.forEach完成?

时间:2020-09-03 08:05:26

标签: flutter dart

示例代码

Map<String,String> gg={'gg':'abc','kk':'kojk'};

Future<void> secondAsync() async {
  await Future.delayed(const Duration(seconds: 2));
  print("Second!");
  gg.forEach((key,value) async{await Future.delayed(const Duration(seconds: 5));
  print("Third!");
});
}

Future<void> thirdAsync() async {
  await Future<String>.delayed(const Duration(seconds: 2));
  print('third');
}

void main() async {
  secondAsync().then((_){thirdAsync();});
}

输出

Second!
third
Third!
Third!

如您所见,我要等到地图的foreach循环完成后再打印third
预期产量

Second!
Third!
Third!
third

3 个答案:

答案 0 :(得分:5)

Map.forEach(以及类似的Iterable.forEach)用于在集合的每个元素上执行一些代码,以产生副作用。返回值将被忽略。因此,如果您提供的函数返回一个Future,则Future将会丢失,并且在完成时将不会通知您。因此,您不能等待每个迭代完成,也不能等待所有迭代完成。

请勿将.forEachasync回调一起使用。

相反,如果要依次等待每个async回调,请使用常规的for循环:

for (var mapEntry in gg.entries) {
  await Future.delayed(const Duration(seconds: 5));
}

或者如果您真的更喜欢使用.forEach语法,则可以使用Future.forEach

await Future.forEach([
  for (var mapEntry in gg.entries)
    Future.delayed(const Duration(seconds: 5)),
]);

如果您想允许您的async回调可能并行运行,则可以使用Future.wait

await Future.wait([
  for (var mapEntry in gg.entries)
    Future.delayed(const Duration(seconds: 5)),
]);

如果尝试将异步函数用作Map.forEachIterable.forEach回调(以及许多类似的StackOverflow问题列表),请参见https://github.com/dart-lang/linter/issues/891,以获取分析器警告的请求。 / p>

答案 1 :(得分:0)

Map<String,String> gg={'gg':'abc','kk':'kojk'};

Future<void> secondAsync() async {
  await Future.delayed(const Duration(seconds: 2));
  print("Second!");`
  
  gg.forEach((key,value) {Future.delayed(const Duration(seconds: 5));

  print("Third!");
});
}

Future<void> thirdAsync() async {
  await Future<String>.delayed(const Duration(seconds: 2));
  print('third');
}

void main() async {
  secondAsync().then((_){thirdAsync();});
}

``

答案 2 :(得分:0)

我相信您正在寻找这个。

  Future<void> secondAsync() async {
    await Future.delayed(const Duration(seconds: 2));
    print("Second!");
    await Future.forEach(gg.values, (element) async {
      await Future.delayed(const Duration(seconds: 5));
      print("Third!");
    });
  }