【问题标题】:How to call an async API fully synchronously within a loop in Dart?如何在 Dart 的循环中完全同步地调用异步 API?
【发布时间】:2022-01-28 05:33:23
【问题描述】:

如何在 Dart 的循环中完全同步地调用异步 API?

例如,如果我有

for(...) {
  await doSomethingLongAsync();
}

据我了解,doSomethingLongAsync() 将在循环的每次迭代中按顺序但异步调用,即循环的每个后续迭代将异步调用 doSomethingLongAsync() 甚至在前一次迭代的调用完成之前。

我需要确保循环的后续迭代不会调用 doSomethingLongAsync(),直到上一次迭代对同一函数的调用完全完成。

【问题讨论】:

  • "即循环的每个后续迭代都将异步调用 doSomethingLongAsync() 甚至在前一个迭代的调用完成之前。"这种理解是错误的。 await 表示该代码在 doSomethingLongAsync 完成之前不会恢复执行。
  • 但是,请注意,当您等待每次调用 doSomethingLongAsync 完成时,可能会触发带有循环再次的代码,这将创建一个单独的对doSomethingLongAsync 的调用集。不过,那将是一个不同的问题。
  • @jamesdlin,谢谢!是的,可能就是这种情况——循环的双重输入。
  • @jamesdlin,是的,看起来我同时在循环中获得了多个条目,为响应流事件而调用。 Dart 中有没有办法拥有像互斥体/临界区这样的东西?
  • @AKornich 所有这些事件都源自单个Stream 对象吗?如果是这样,我会考虑使用asyncMap (api.dart.dev/stable/2.15.1/dart-async/Stream/asyncMap.html) 处理事件或使用await for (dart.dev/tutorials/language/streams#receiving-stream-events) 处理事件。任何一个都应该允许您按顺序处理流事件。

标签: dart asynchronous async-await synchronization


【解决方案1】:

据我了解,doSomethingLongAsync() 将在循环的每次迭代中按顺序但异步调用,即循环的每个后续迭代将异步调用 doSomethingLongAsync() 甚至在前一次迭代的调用完成之前。

这是不正确的,当您 await 时,它不会继续(在 async 函数的上下文中),直到正在等待的 Future 完成。

我需要确保循环的后续迭代不会调用 doSomethingLongAsync(),直到上一次迭代对同一函数的调用完全完成。

你写的代码已经做到了。

为了说明,尝试运行以下代码:

Future<void> main() async {
  for (int i = 0; i < 10; i++) {
    print('start loop $i');
    await doSomethingLongAsync(i);
    print('end loop $i\n');
  }
}

Future<void> doSomethingLongAsync(int i) async {
  print('start doSomethingLongAsync $i');
  await Future.delayed(const Duration(seconds: 2));
  print('end doSomethingLongAsync $i');
}

您将看到它不会继续循环的下一次迭代,直到正在等待的 Future 完成。

【讨论】:

    猜你喜欢
    • 2020-04-12
    • 2020-07-03
    • 2013-02-16
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多