【问题标题】:Using loops with Futures in Dart在 Dart 中使用带有 Future 的循环
【发布时间】:2014-08-17 17:29:00
【问题描述】:

好的,所以我有一个文件列表,我需要对列表的每个成员运行一个函数。我基本上想做这样的事情:

for(File file in files) {
    functionThatReturnsAFuture(file);
}

但这显然行不通,因为返回 Future 的函数是异步触发的。我唯一的选择是这样的吗?

List<File> files = new List<File>();
// Add files somewhere

Future processFile(int i) {
   return new Future.sync(() {
       //Do stuff to the file
       if(files.length>i+1) {
           return processFile(i+1);
       }
   });
}

processFile(0);

编辑: 我想更多的背景很重要。最终目标是将多个文件组合成一个 JSON 对象以提交到服务器。 FileReader 对象使用事件来执行读取,因此我使用 Completer 创建了一个提供 Future 的包装函数。我可以让所有这些异步运行,然后在它们全部完成后触发一个提交它的事件,但相对于一个 for-each-loop 而言,这是相对大量的设置(如果存在的话,无论如何) )。核心问题是需要在文件列表上运行一个未来返回函数,然后执行一个依赖于它们都已完成的操作。

【问题讨论】:

  • 你的第一个例子有什么问题?函数是否异步运行有什么关系?
  • 我用更多信息编辑了问题。

标签: dart future


【解决方案1】:

当你需要等待多个Futures完成且不关心订单时,可以使用Future.wait()

Future.wait(files.map(functionThatReturnsAFuture))
  .then((List response) => print('All files processed'));

如果顺序很重要,您可以使用 Future.forEach() 代替它等待每个 Future 完成,然后再移动到下一个元素:

Future.forEach(files, functionThatReturnsAFuture)
  .then((response) => print('All files processed'));

【讨论】:

  • 这太完美了。非常感谢!我可以问一下如果订单很重要你会怎么做吗?
  • 很高兴为您提供帮助。我已经添加了更多信息来解决这种情况。
  • 这样,我终于有足够的声誉来 +1 答案。你得到我的第一个 +1!
  • Fjuture.wait 需要一个 Iterable,所以不需要先创建一个 List。只需Future.wait(files.map(functionThatReturnsAFuture))
  • @lrn 啊,谢谢,Future.wait 代码比 Future.forEach 长,这让我很困扰。
【解决方案2】:

Dart 支持 async/await 已经有一段时间了,它允许它写成

someFunc() async {
  for(File file in files) {
    await functionThatReturnsAFuture(file);
  }
}

【讨论】:

  • 我正在更改接受的答案,因为现在应该这样做。
  • 我很难理解这是如何工作的。我有更多的内在方法。就像 functionThatReturnsAFuture 方法里面的另一个方法一样。所以最初没有工作。然后我为所有内部方法添加了相同的 async/await 组合。然后开始按预期工作。
  • 在方法调用前等待,在方法签名后异步。不要错过这些。
【解决方案3】:

这个库可以帮助https://pub.dartlang.org/packages/heavylist

HeavyList<File> abc = new HeavyList<File>([new File(), new File(), ]);
abc.loop(new Duration(seconds: 1), (List<File> origin) {
print(origin);
}, (File item, Function resume) {
  //simulating an asynchronous call
  print(item);
  //move to next item
  resume();
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多