doWhile 静态方法

Future<void> doWhile(
  1. FutureOr<bool> action()
)

重复执行操作,直到返回 false

操作 action 可能是同步的或异步的。

只要操作返回布尔值 true 或一个完成值为 trueFuture<bool>,就会重复调用该操作。

如果调用 action 返回 false 或一个完成值为 falseFuture,迭代结束,并且 doWhile 返回的 future 将以 null 值完成。

如果调用 action 抛出异常或由 action 返回的 future 以错误完成,迭代结束,并且 doWhile 返回的 future 将以相同的错误完成。

action 的调用可以在任何时间发生,包括在调用 doWhile 之后立即发生。唯一的限制是新的 action 调用不会在之前的调用返回之前发生,并且如果它返回了一个 Future<bool>,则不会在该 future 完成之前发生。

示例

void main() async {
  var value = 0;
  await Future.doWhile(() async {
    value++;
    await Future.delayed(const Duration(seconds: 1));
    if (value == 3) {
      print('Finished with $value');
      return false;
    }
    return true;
  });
}
// Outputs: 'Finished with 3'

实现

static Future<void> doWhile(FutureOr<bool> action()) {
  _Future<void> doneSignal = new _Future<void>();
  late void Function(bool) nextIteration;
  // Bind this callback explicitly so that each iteration isn't bound in the
  // context of all the previous iterations' callbacks.
  // This avoids, e.g., deeply nested stack traces from the stack trace
  // package.
  nextIteration = Zone.current.bindUnaryCallbackGuarded((bool keepGoing) {
    while (keepGoing) {
      FutureOr<bool> result;
      try {
        result = action();
      } catch (error, stackTrace) {
        // Cannot use _completeWithErrorCallback because it completes
        // the future synchronously.
        _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace);
        return;
      }
      if (result is Future<bool>) {
        result.then(nextIteration, onError: doneSignal._completeError);
        return;
      }
      keepGoing = result;
    }
    doneSignal._complete(null);
  });
  nextIteration(true);
  return doneSignal;
}