Flutter:Future.doWhile结束超时异常



在捕获超时错误后,我在Future.doWhile中遇到了不停止迭代的问题。

下面是我的示例函数代码:

Future<void> testFunction() async {
print(">>> start test");
int sec = 0;
await Future.doWhile(() async {
await Future.delayed(Duration(seconds: 5));
sec += 5;
if (sec >= 60) {
print("> end doWhile after 60 seconds");
return false;
}
print("> elapsed $sec seconds");
return true;
}).timeout(Duration(seconds: 20)).then(print).catchError(print);
print(">>> end test");
}

结果:

I/flutter ( 6081): >>> start test
I/flutter ( 6081): > elapsed 5 seconds
I/flutter ( 6081): > elapsed 10 seconds
I/flutter ( 6081): > elapsed 15 seconds
I/flutter ( 6081): TimeoutException after 0:00:20.000000: Future not completed
I/flutter ( 6081): >>> end test
I/flutter ( 6081): > elapsed 20 seconds
I/flutter ( 6081): > elapsed 25 seconds
I/flutter ( 6081): > elapsed 30 seconds
I/flutter ( 6081): > elapsed 35 seconds
I/flutter ( 6081): > elapsed 40 seconds
I/flutter ( 6081): > elapsed 45 seconds
I/flutter ( 6081): > elapsed 50 seconds
I/flutter ( 6081): > elapsed 55 seconds
I/flutter ( 6081): > end doWhile after 60 seconds

为什么doWhile的迭代在catch超时错误后有效?

超时方法

Future<T> timeout (
Duration timeLimit,
{FutureOr<T> onTimeout(
)}
) 

并不意味着停止执行它所调用的Future。你可以认为它相当于一个简单的延迟方法,它等待timeLimit持续时间让Future返回一个值。如果Future没有在timeLimit中完成,您就有机会使用onTimeout进行一些工作,这样代码就不会中断。

如果你真的想在你的情况下停止执行doWhile方法,你可以这样实现:

Future<void> testFunction() async {
print(">>> start test");
var toContinue = true;
int sec = 0;
await Future.doWhile(() async {
await Future.delayed(Duration(seconds: 1));
sec += 1;
if (sec >= 5) {
print("> end doWhile after 5 seconds");
return false;
}
print("> elapsed $sec seconds");
return toContinue;
}).timeout(Duration(seconds: 3), onTimeout: () {
toContinue = false;
print('> Timed Out');
});
print(">>> end test");
}

输出:

>>> start test
> elapsed 1 seconds
> elapsed 2 seconds
> Timed Out
>>> end test
> elapsed 3 seconds

甚至这位作者对超时方法也是错误的

如果您运行有关的代码。您将看到0超时,并且永远不会看到未来0的延迟完成。

进一步阅读:
Future.timeout文档具有误导性
增加了真正取消/处置Fututre 的可能性

最新更新