Performs an operation repeatedly until it returns false
.
The operation, f
, may be either synchronous or asynchronous.
The operation is called repeatedly as long as it returns either the bool
value true
or a Future<bool>
which completes with the value true
.
If a call to f
returns false
or a Future that completes to false
,
iteration ends and the future returned by doWhile is completed with
a null
value.
If a call to f
throws or a future returned by f
completes with
an error, iteration ends and the future returned by doWhile
completes with the same error.
Calls to f
may happen at any time, including immediately after calling
doWhile
. The only restriction is a new call to f
won't happen before
the previous call has returned, and if it returned a Future<bool>
, not
until that future has completed.
Source
static Future doWhile(FutureOr<bool> f()) { _Future doneSignal = new _Future(); var 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.bindUnaryCallback((bool keepGoing) { while (keepGoing) { FutureOr<bool> result; try { result = f(); } 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); }, runGuarded: true); nextIteration(true); return doneSignal; }