您可以使用CancelableOperation 或CancelableCompleter 取消未来。请参阅下面的 2 个版本:
解决方案 1:CancelableOperation(包含在测试中,您可以自己尝试):
test("CancelableOperation with future", () async {
var cancellableOperation = CancelableOperation.fromFuture(
Future.value('future result'),
onCancel: () => {debugPrint('onCancel')},
);
// cancellableOperation.cancel(); // uncomment this to test cancellation
cancellableOperation.value.then((value) => {
debugPrint('then: $value'),
});
cancellableOperation.value.whenComplete(() => {
debugPrint('onDone'),
});
});
test("CancelableOperation with stream", () async {
var cancellableOperation = CancelableOperation.fromFuture(
Future.value('future result'),
onCancel: () => {debugPrint('onCancel')},
);
// cancellableOperation.cancel(); // uncomment this to test cancellation
cancellableOperation.asStream().listen(
(value) => { debugPrint('value: $value') },
onDone: () => { debugPrint('onDone') },
);
});
以上两个测试都会输出:
then: future result
onDone
现在,如果我们取消注释 cancellableOperation.cancel();,那么上述两个测试都会输出:
onCancel
解决方案 2:CancelableCompleter(如果您需要更多控制)
test("CancelableCompleter is cancelled", () async {
CancelableCompleter completer = CancelableCompleter(onCancel: () {
print('onCancel');
});
// completer.operation.cancel(); // uncomment this to test cancellation
completer.complete(Future.value('future result'));
print('isCanceled: ${completer.isCanceled}');
print('isCompleted: ${completer.isCompleted}');
completer.operation.value.then((value) => {
print('then: $value'),
});
completer.operation.value.whenComplete(() => {
print('onDone'),
});
});
输出:
isCanceled: false
isCompleted: true
then: future result
onDone
现在,如果我们取消注释 cancellableOperation.cancel();,我们会得到输出:
onCancel
isCanceled: true
isCompleted: true
请注意,如果您使用await cancellableOperation.value 或await completer.operation,那么future 将永远不会返回结果,并且如果操作被取消,它将无限期地等待。这是因为await cancellableOperation.value 与写cancellableOperation.value.then(...) 相同,但如果操作被取消,则永远不会调用then()。
记得添加async Dart 包。
Code gist