【问题标题】:Await inside for loop is admitted in Dart?在 Dart 中是否允许在 for 循环中等待?
【发布时间】:2017-05-13 13:18:43
【问题描述】:

我有一个类似下面的程序:

main() async {
  ooClass = new OoClass(1);
  int val = await function1();
  print(val);
  ooClass = new OoClass(2);
  val = await function1();
  print(val);
  ooClass = new OoClass(3);
  val = await function1();
  print(val);

}

OoClass ooClass;

Future<int> function1() async {
  List list3 = await function2();
  return list3.indexOf('Ok');
}


Future<List<String>> function2() async {

  List<String> list1 = new List<String>();

  function3(Map<String, int> map1) async {
    String string1 = '';
    bool bool1 = false;
    List<String> list2 = [];
    String string2;

    function4(String string3) async {
      if (ooClass.function7(string3)) return;
      if (ooClass.function8() && !bool1) {
        bool1 = true;
        return;
      }
      string2 = await function5(string3);
      list2.add(string2);
    }

    for (String key in map1.keys) {
      await function4(key);
    }
    string1 = list2.join(', ');
    list1.add(string1);
  }

  for (Map<String, int> idxList in ooClass.function6()) {
    await function3(idxList);
  }
  return list1;
}

function5(String s1) {
  return new Future.value('Ok');
}

class OoClass {

  List<Map<String, int>> map2;
  bool bool3 = false;

  OoClass(int type) {
    switch(type) {
      case 1:
        map2 = [{'Ok':1}];
        break;
      case 2:
        map2 = [{'id': 1, 'Ok':1}];
        break;
      case 3:
        map2 = [{'foo': 1, 'Ok':1}];
        bool3 = true;
        break;
    }
  }

  List<Map<String, int>> function6() {
    return map2;
  }

  bool function7(String string9) {
    if (string9 == 'id') return true;
    return false;
  }

  bool function8() {
    return bool3;
  }
}

这个 sn-p 完美运行。

在我的真实环境中,当 await function4(key);被调用时,function2 返回 list1 列表(空)。 Function4 调用稍后执行,但 function2 的结果丢失。

我真的不明白这种行为。可能是一个错误或 for 循环中的 await 不被使用? 如果 await 不应该在 for 循环中使用,我该如何以另一种方式实现它?

我正在使用 dart 1.22.0-dev.4,但我也尝试过使用较旧(和稳定)的版本,结果相同。


我终于遇到了问题,它不依赖于 for 循环中的 await。相反,这是我的代码中的错误。

【问题讨论】:

  • await in for 很好。您的代码示例太复杂,无法进一步调查。

标签: for-loop dart async-await


【解决方案1】:

是的,await 在 Dart 的 for 循环中是允许的,它会按预期工作。

for (var o in objects) {
  await doSomething(o);
}

甚至还有 await for 用于 Streams,如果您正在寻找的话:

await for (var event in eventStream) {
  print("Event received: $event");
}

您在 DartPad 中的示例 works correctly。它过于复杂和抽象,无法调试,但至少从表面上看,它应该可以工作。但是,您说 sn-p 在您的“真实环境”中不起作用。如果您解释一下您的意思,也许我们可以提供帮助?

附加提示:take full advantage of static analysis,尤其是await_only_futuresunawaited_futures linter 规则。这可以帮助您捕获许多错误。

【讨论】:

    【解决方案2】:

    List.forEachFuture.forEach

    如果您碰巧在List 上使用.forEach(),这将不起作用:

    someList.forEach((item) async {
      await longFunc(item);
    )}
    

    你需要使用:

    await Future.forEach(someList, (item) async {
      await longFunc(item);
    });
    

    我错误地认为这适用于List.forEach,直到找到this answer

    【讨论】:

    • 请注意,虽然这是最好的方法,但编译器不会知道块中 item 的类型。所以你可能需要打电话给await Future.forEach&lt;TypeOfSomeList&gt;(someList, (item) async {
    猜你喜欢
    • 2020-02-21
    • 2021-03-15
    • 2018-06-09
    • 2018-01-06
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    相关资源
    最近更新 更多