【问题标题】:How to wait for forEach to complete with asynchronous callbacks?如何等待 forEach 完成异步回调?
【发布时间】:2021-11-13 08:39:13
【问题描述】:

示例代码

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

【问题讨论】:

    标签: flutter dart asynchronous callback


    【解决方案1】:

    你可以像这样使用Future.forEach

    main() async {
      print("main start");
      await asyncOne();
      print("main end");
    }
    
    asyncOne() async {
      print("asyncOne start");
      await Future.forEach([1, 2, 3], (num) async {
        await asyncTwo(num);
      });
      print("asyncOne end");
    }
    
    asyncTwo(num) async
    {
      print("asyncTwo #${num}");
    }
    

    【讨论】:

      【解决方案2】:

      Iterable.forEachMap.forEachStream.forEach 旨在对集合的每个元素执行一些代码以实现副作用。他们接受具有void 返回类型的回调。因此,那些.forEach 方法不能使用回调返回的任何值,包括返回的Futures。如果您提供一个返回 Future 的函数,则该 Future 将丢失,并且您将无法在它完成时收到通知。因此,您不能等待每次迭代完成,也不能等待所有迭代完成。

      不要将.forEach 与异步回调一起使用。

      相反,如果您想依次等待每个异步回调,只需使用普通的for 循环:

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

      (一般情况下,I recommend using normal for loops over .forEach 在除特殊情况外的所有情况下。Effective Dart has a mostly similar recommendation。)

      如果您真的更喜欢使用.forEach 语法并希望连续等待每个Future,则可以使用Future.forEach确实期望回调返回Futures):

      await Future.forEach(
        gg.entries,
        (entry) => Future.delayed(const Duration(seconds: 5)),
      );
      

      如果你想让你的异步回调可能并行运行,你可以使用Future.wait

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多