3

我必须编写一个耗时的函数,如果它准备好了,它将返回一个 Future。下面的方法是否正确,或者我在第 9 行中的耗时算法是否会阻止程序直到它准备好。在这种情况下,我该怎么做才能将控制权交还给事件循环,或者还有什么可以解决的?

Future<int> timeconsumingFunctionReturningFuture(int i) {
  var completer = new Completer();

  if (i==0) { 
    completer.completeError(88);
    return completer.future;
  } else {
    int rc;
    // Line9: rc = timeconsuming algorithm, to calculate rc
    completer.complete(rc);
    return completer.future;
  }
}

Tnx米查

4

2 回答 2

3

您的代码可能无法按预期工作,因为您的算法可能会阻止完成者的返回。试试这种方式:

Future<int> timeconsumingFunctionReturningFuture(int i) {
  var completer = new Completer();

  if (i==0) { 
    completer.completeError(88);
  } else {
    Timer.run(() {
      int rc;
      // Line9: rc = timeconsuming algorithm, to calculate rc
      completer.complete(rc);
    });
  }
  return completer.future;
}

这样,您的耗时算法将异步运行,并立即返回未来。

我自己没有尝试过,但这个较短的版本也应该可以工作(不创建完成者)

return new Future.delayed(Duration.ZERO, () {
    // timeconsuming algorithm
  });
于 2014-01-01T12:59:00.703 回答
2

Günter Zöchbauer 的解决方案是正确的,但您可以简化代码:

Future<int> timeconsumingFunctionReturningFuture(int i) {
  if (i == 0) return new Future.error(88);
  return new Future(() {
    int rc;
    // Line9: rc = timeconsuming algorithm, to calculate rc
    return rc;
  });
}

或者,您甚至可以将错误检查放入 Future 中:

Future<int> timeconsumingFunctionReturningFuture(int i) {
  return new Future(() {
    if (i == 0) throw 88;
    int rc;
    // Line9: rc = timeconsuming algorithm, to calculate rc
    return rc;
  });
}

另请注意:如果传递 0i是一个错误(程序员错误),那么同步抛出通常是可以的。然后它的行为方式与在检查模式下传递字符串的方式相同。

于 2014-01-02T07:57:43.557 回答