取消dart(flutter)中Future的执行

首先要明确的一点是, 在dart协程式的编程语言中, 是无法中断一个Future的执行的, 我们所能做的只能是取消一个async代码块的回调, 也就是说一段异步代码块执行后, 准备继续执行后续的回调代码时, 由于已经被取消, 而中止了整个过程.
由于在dart中有回调机制并能被中止的有Futhre.then()和Stream.listen(), 所以下面就有相应的实现方法。

方法1: 使用CancelableOperation

下面是一个异步获取数据, 当页面销毁时中断渲染的示例代码:

import 'package:async/async.dart';
void loadPageDatas() async {
  CancelableOperation cancelTask = CancelableOperation.fromFuture(
    Future(() async {
      print('start query datas');
      await Future.delayed(Duration(seconds: 6));
      print('end query datas');
      return "value";
    }),
    onCancel: () => print('disposed, cancel rendering.'),
  );
  cancelTask.value.then((val) {
    print('to render tree: $val ');  // 不能放在cancelTask的构造函数中, 需要通过  cancelTask.value.then进行添加.
  });

  Future.delayed(Duration(seconds: 3)).then((_) {
    // when disposed
    cancelTask.cancel();
  });
}

有一些细节, 通过源码cancelable_operation.dart::CancelableCompleter()实现可以知道, 由于CancelableOperation是对Future的then进行了接管, 判断isCanceled标记以决定是否需要执行用户提供的then(), 但这个接管是在CancelableCompleter()构造完成后的 cancelTask.value中进行的,

所以在CancelableOperation.fromFuture()只提供不可中断的功能(如querying datas), 将可中断的功能(如rendering)放在构造完成后的.value.then中添加,

这是需要注意的,否则会出现即使cancel()后仍会执行的情况。
CancelableOperation 类的本质是有个 CancelableCompleter 类, 在其中完成了cancel的操作, 可以阅读源码.

方法2:使用Stream.

同样的示例代码, 很简单:

Future<String> getData() async {
  print('into getData');
  await Future.delayed(Duration(seconds: 5));
  print('leave getData');
  return "value";
}
void loadPageDatas() async {
  StreamSubscription<String> dataSub =
      getData().asStream().listen((String data) {
    print('rendering data: $data');
  });
  Future.delayed(Duration(seconds: 3), () => dataSub.cancel());
}

代码比较清晰, 不多解释了。
参考来源:
https://dart.academy/how_cancel_future/


有个题外话,在使用Future.delayed(Duration(seconds: 3, milliseconds: 100))时,要小心精度问题,比如Duration(seconds: 3, milliseconds: 100)有可能比Duration(seconds: 3) 要先被执行,这牵涉到task的调度,还没有深究,有时间了再做研究。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容