Await inside for loop is admitted in Dart?

2020-03-01 16:17发布

问题:

I have a program like the following:

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;
  }
}

This snippet works perfectly.

In my real environment, instead, when await function4(key); is called, function2 returns the list1 List (empty). Function4 call is executed later but the result of function2 is lost.

I don't really understand this behavior. Could it be a bug or await inside for loop is not to be used? If await should not be used inside for loop how could I implement it in another way?

I'm using dart 1.22.0-dev.4 but I've tried also with older (and stable) versions and I had the same result.


I finally got the problem and it did not depend on await in a for loop. It was instead an error in my code.

回答1:

Yes, await is permitted inside a for loop in Dart, and it will work as expected.

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

And there is even await for for Streams, if that's what you're looking for:

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

Your example works correctly in DartPad. It's too complex & abstract to debug but, at least superficially, it should work. You say that the snippet doesn't work in your "real environment", though. Maybe we could help if you explained what you mean by that?

Additional tip: take full advantage of static analysis, especially the await_only_futures and unawaited_futures linter rules. This can help you catch many bugs.



回答2:

Here is your answer

/// Declare a list
List<String> _list = ['a','b','c'];

// pass the list and a callback function
 await Future.forEach(_list, (str) async {
      print(str);
    });