在这些情况下,我需要尝试某事一段时间或多次,但不会太久。 Future
的 .timeout
属性看起来是一个自然的选择。我了解到,原始的 Future
即使在超时后仍继续运行,例如:
Future<void> trySomething() async {
while (true) {
print('trying something...');
bool successful = false; // exit if done
if (successful) {
return;
}
await Future.delayed(const Duration(seconds: 1));
}
}
trySomething().timeout(const Duration(seconds: 10), onTimeout: () {
print('try something else...');
});
以上代码产生以下输出:
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): try something else...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
我不太优雅的解决方法是使用外部标志变量向 main future 中的进程指示不再需要其服务:
bool youAreTooLate = false;
Future<void> trySomething() async {
while (true) {
if (youAreTooLate) {
return;
}
print('trying something...');
bool successful = false; // exit if done
if (successful) {
return;
}
await Future.delayed(const Duration(seconds: 1));
}
}
trySomething().timeout(const Duration(seconds: 10), onTimeout: () {
youAreTooLate = true;
print('try something else...');
});
这产生了下面的预期结果,但并没有让我内心变得那么温暖和模糊。
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): trying something...
I/flutter (26426): try something else...
有没有更好的方法来处理这种情况?
最佳答案
如果您只是想重复做一些有延迟的事情,您可以使用 Timer
来实现这一点,同时保持取消它的能力。
final timer = Timer.periodic(const Duration(seconds: 1), (t) {
// Do repeated work here.
if (shouldCancel) {
// This is the 'timer' object.
t.cancel();
}
});
Future.delayed(const Duration(seconds: 10)).then((_) => timer.cancel());
如果您希望真正等待计时器内部的工作完成后再重试,您可以这样做:
Timer timer;
doWork() async {
// Do your work here.
// ...
if (retry) {
timer = Timer(const Duration(seconds: 1), doWork);
}
}
Future.delayed(const Duration(seconds: 10)).then((_) => timer?.cancel());
这应该可行,但如果您已经有一个未完成的 Future
,则无法实际取消它。
关于flutter - 取消 future 超时的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59673144/