doWhile 静态方法

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

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

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

    只要操作的返回值是 bool 类型的 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;
    }