I have problem with dosen't stop iteration in Future.doWhile after catch timeout error.
Below is code my example function:
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");
}
and result:
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
Why doWhile's iteration works after catch timeout error?
The timeout method
Future<T> timeout (
Duration timeLimit,
{FutureOr<T> onTimeout(
)}
)
isn't meant to stop the execution of the Future it's called on. You can think of it equivalent to simply a delayed method which waits for timeLimit duration for the Future to return a value. If Future doesn't complete in timeLimit you get a chance to do some work with onTimeout so code doesn't break.
If you really want to stop execution of doWhile method in your case, you could implement it like this:
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");
}
Output:
>>> start test
> elapsed 1 seconds
> elapsed 2 seconds
> Timed Out
>>> end test
> elapsed 3 seconds
Even this author is wrong about timeout method
If you run the code about. You’ll see 0 timed out and you'll never see Delay complete for Future 0.
For further reading:
Future.timeout documention is misleading
Add possibility to truly cancel/dispose Fututre
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With