doWhile 静态方法
重复执行一个操作,直到它返回 false
。
操作的 action
可以是同步的或异步的。
只要操作的返回值是 bool 类型的 true
或一个完成值为 true
的 Future<bool>
,操作就会重复调用。
如果对 action
的调用返回 false
或一个完成值为 false
的 Future,则迭代结束,由 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;
}