doWhile 静态方法
重复执行操作,直到返回 false
。
操作 action
可能是同步的或异步的。
只要操作返回布尔值 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;
}