Flutter可取消操作插件cancellable的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter可取消操作插件cancellable的使用

cancellable 是一个用于在任务执行过程中提供取消能力的Flutter插件。它允许通过一定的机制终止或撤销正在进行的操作。下面将详细介绍如何使用这个插件,并提供完整的示例代码。

使用方法

基本用法

首先,我们需要导入 cancellable 包,并创建一个 Cancellable 实例。然后可以将任何流(Stream)绑定到这个实例上,这样就可以在需要的时候取消这些流的操作。

import 'dart:async';
import 'package:cancellable/cancellable.dart';

void main() {
  Cancellable cancellable = Cancellable();

  // 创建一个每100毫秒发射一次的流
  Stream.periodic(Duration(milliseconds: 100), (i) => i)
      .bindCancellable(cancellable.makeCancellable()) // 将流与cancellable关联
      .listen((event) => print(event)); // 监听并打印每个事件

  // 在1秒后取消流
  Future.delayed(Duration(seconds: 1)).then((value) => cancellable.cancel());

  // 输出:
  // 0
  // 1
  // 2
  // ...
  // 9
}

使用 withRunZone 方法

withRunZone 方法允许在一个独立的区域中运行异步任务,并且可以在任务被取消时捕获特定的异常。

Cancellable cancellable2 = cancellable.makeCancellable();

try {
  await cancellable2.withRunZone(() async {
    print('withRunZone 1');
    await Future.delayed(Duration(milliseconds: 200));
    print('withRunZone 2');
    await Future.delayed(Duration(milliseconds: 200));
    print('withRunZone 3');
    await Future.delayed(Duration(milliseconds: 200));
    print('withRunZone 4');
    await Future.delayed(Duration(milliseconds: 200));
    print('withRunZone 5');
    await Future.delayed(Duration(milliseconds: 200));
    print('withRunZone 6');
  }, ignoreCancelledException: true); // 忽略取消异常
} catch (err) {
  print('xxxxxxxx  $err');
}

// 输出:
// withRunZone 1
// withRunZone 2
// withRunZone 3
// withRunZone 4
// withRunZone 5

完整示例 Demo

以下是一个更完整的示例,展示了如何结合上述两种方式来使用 cancellable 插件:

import 'dart:async';
import 'package:cancellable/cancellable.dart';

void main() async {
  // 创建一个新的可取消实例
  Cancellable cancellable = Cancellable();

  // 创建一个周期性流并绑定到cancellable
  Stream.periodic(Duration(milliseconds: 100), (i) => i)
      .bindCancellable(cancellable.makeCancellable())
      .listen((event) => print(event));

  // 设置一个延迟,在1秒后取消操作
  Future.delayed(Duration(seconds: 1)).then((value) => cancellable.cancel());

  // 另一个cancellable实例
  Cancellable cancellable2 = cancellable.makeCancellable();

  try {
    await cancellable2.withRunZone(() async {
      print('withRunZone 1');
      await Future.delayed(Duration(milliseconds: 200));
      print('withRunZone 2');
      await Future.delayed(Duration(milliseconds: 200));
      print('withRunZone 3');
      await Future.delayed(Duration(milliseconds: 200));
      print('withRunZone 4');
      await Future.delayed(Duration(milliseconds: 200));
      print('withRunZone 5');
      await Future.delayed(Duration(milliseconds: 200));
      print('withRunZone 6');
    }, ignoreCancelledException: true);
  } catch (err) {
    print('xxxxxxxx  $err');
  }
}

更多关于Flutter可取消操作插件cancellable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter可取消操作插件cancellable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,如果你需要使用一个支持可取消操作的插件,比如cancellable(虽然Flutter生态系统中没有一个广泛认可的名为cancellable的官方或主流插件,但我们可以实现类似的功能),你可以通过自定义一个可取消的Future来完成这一任务。下面是一个示例代码,展示了如何创建一个可取消的Future操作。

首先,我们需要定义一个CancellableFuture类,该类允许我们启动一个任务并能够取消它。

import 'dart:async';

class CancellableFuture<T> {
  final Completer<T> _completer = Completer<T>();
  bool _isCancelled = false;
  final Future<T> _future;
  final Future<void> Function() _cancelFunction;

  CancellableFuture(Future<T> Function() startFunction, Future<void> Function() cancelFunction)
      : _future = _startFuture(startFunction),
        _cancelFunction = cancelFunction {
    // This ensures that if the future completes normally, we mark it as not cancelled.
    _future.whenComplete(() => _isCancelled = false);
  }

  Future<T> get future => _future;

  bool get isCancelled => _isCancelled;

  Future<void> cancel() async {
    if (!_isCancelled) {
      _isCancelled = true;
      await _cancelFunction();
      if (!_completer.isCompleted) {
        _completer.completeError(CancellationError());
      }
    }
  }

  Future<T> _startFuture(Future<T> Function() startFunction) async {
    try {
      return await startFunction();
    } catch (error, stackTrace) {
      _completer.completeError(error, stackTrace);
      rethrow;
    }
  }
}

接下来,我们可以使用这个CancellableFuture类来执行一个可取消的操作。例如,一个模拟的长时间运行任务:

import 'dart:async';

Future<int> longRunningTask() async {
  await Future.delayed(Duration(seconds: 5));
  return 42; // Simulated result
}

Future<void> cancelLongRunningTask() async {
  // In a real-world scenario, this might release resources or stop some ongoing process.
  print('Long running task cancelled.');
}

void main() async {
  // Create a cancellable future for the long running task
  CancellableFuture<int> cancellableFuture = CancellableFuture(
    () => longRunningTask(),
    cancelLongRunningTask,
  );

  // Start a timer to cancel the task after 2 seconds
  Timer(Duration(seconds: 2), () {
    if (!cancellableFuture.isCancelled) {
      cancellableFuture.cancel();
    }
  });

  try {
    int result = await cancellableFuture.future;
    print('Task completed with result: $result');
  } on CancellationError {
    print('Task was cancelled.');
  } catch (error) {
    print('Task failed with error: $error');
  }
}

在这个例子中,longRunningTask是一个模拟的长时间运行任务,它会在5秒后完成。我们创建了一个CancellableFuture实例来管理这个任务,并提供了一个cancelLongRunningTask函数来取消任务(尽管在这个简单例子中它只是打印一条消息)。然后,我们使用一个Timer在2秒后尝试取消任务。

当任务被取消时,cancellableFuture.future会抛出一个CancellationError,我们可以在try-on-catch块中捕获这个错误并处理它。

请注意,这个实现是一个简单的示例,用于演示如何在Flutter中实现可取消的Future操作。在实际应用中,你可能需要更复杂的逻辑来处理取消操作,比如释放资源、停止后台线程等。

回到顶部