如何链接异步任务?

时间:2014-04-30 09:46:29

标签: asynchronous dart

我有一个网址列表,我必须按顺序检查。当在网址上检索到的内容之一与给定条件匹配时,我必须停止,否则必须测试下一个网址。

问题是检索给定网址的内容是一个异步任务,所以我不能使用简单的for-each循环。

最好的方法是什么?

现在我的代码看起来像这样:

List<String> urls = [/*...*/];
void f() {
  if (urls.isEmpty) return; // no more url available
  final url = urls.removeAt(0);
  getContent(url).then((content) {
    if (!matchCriteria(content)) f(); // try with next url
    else doSomethingIfMatch();
  });
}
f();

2 个答案:

答案 0 :(得分:1)

Quiver package包含几个用异步迭代的函数。

  

doWhileAsyncreduceAsyncforEachAsync对Iterables上的元素执行异步计算,等待计算在处理下一个元素之前完成。

doWhileAsync似乎正是所需的:

List<String> urls = [/*...*/];
doWhileAsync(urls, (url) => getContent(url).then((content) {
  if (!matchCriteria(content)) {
    return new Future.value(true); // try with next url
  } else {
    doSomethingIfMatch();
    return new Future.value(false);
  }
}));

答案 1 :(得分:0)

我所拥有的一个想法是将整个操作的结果分成另一个Future,其中有反应。此未来传输已找到且有效的URL的内容或可对其作出反应的错误。异步getContent操作的完成要么在结果,错误或再次尝试中完成未来。 请注意,在此(和您的)方法中,在运行操作时,urls列表不得通过任何其他方法进行修改。如果列表是在每个序列的开头创建的(就像示例那样),那么一切都很好。

List<String> urls = [/*...*/];
Completer<String> completer = new Completer<String>();

void f() {
  if (urls.isEmpty) completer.completeError(new Exception("not found"));
  final url = urls.removeAt(0);
  getContent(url).then((content) {
    if (!matchCriteria(content)) f(); // try with next url
    else completer.complete(content);
  }).catchError((error) { completer.completeError(error); });
}

completer.future.then((content) {
  // url was found and content retrieved      
}).catchError((error) {
  // an error occured or no url satisfied the criteria
});