使用异步包(推荐)
async包由 Dart 编程语言的作者开发和发布。它提供了dart:async风格的实用程序来增强异步计算。可以帮助我们取消Future的是CancelableOperation类:
- var myCancelableFuture = CancelableOperation.fromFuture(
- Future<T> inner,
- { FutureOr onCancel()? }
- )
- ?
- // call the cancel() method to cancel the future
- myCancelableFuture.cancel();
为了更清楚,请参阅下面的实际示例。
完整示例
应用预览

我们要构建的应用程序有一个浮动按钮。按下此按钮时,将开始异步操作(这需要 5 秒才能完成)。按钮的背景从靛蓝变为红色,其标签从“开始”变为“取消”,现在您可以使用它来取消Future。
- 如果您在Future完成前 5 秒内点击取消按钮,屏幕将显示“Future已被取消”。
- 如果您什么都不做,则 5 秒后屏幕将显示“Future completed”。
一个演示价值超过一千字:
代码
1.通过执行以下操作安装异步包:
然后运行:
2.main.dart 中的完整源代码(附解释):
- // main.dart
- import 'package:flutter/material.dart';
- import 'package:async/async.dart';
- ?
- void main() {
- runApp(const MyApp());
- }
- ?
- class MyApp extends StatelessWidget {
- const MyApp({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- // Remove the debug banner
- debugShowCheckedModeBanner: false,
- title: '大前端之旅',
- theme: ThemeData(
- primarySwatch: Colors.indigo,
- ),
- home: const HomePage());
- }
- }
- ?
- class HomePage extends StatefulWidget {
- const HomePage({Key? key}) : super(key: key);
- ?
- @override
- _HomePageState createState() => _HomePageState();
- }
- ?
- class _HomePageState extends State<HomePage> {
- // this future will return some text once it completes
- Future<String?> _myFuture() async {
- await Future.delayed(const Duration(seconds: 5));
- return 'Future completed';
- }
- ?
- // keep a reference to CancelableOperation
- CancelableOperation? _myCancelableFuture;
- ?
- // This is the result returned by the future
- String? _text;
- ?
- // Help you know whether the app is "loading" or not
- bool _isLoading = false;
- ?
- // This function is called when the "start" button is pressed
- void _getData() async {
- setState(() {
- _isLoading = true;
- });
- ?
- _myCancelableFuture = CancelableOperation.fromFuture(
- _myFuture(),
- onCancel: () => 'Future has been canceld',
- );
- final value = await _myCancelableFuture?.value;
- ?
- // update the UI
- setState(() {
- _text = value;
- _isLoading = false;
- });
- }
- ?
- // this function is called when the "cancel" button is tapped
- void _cancelFuture() async {
- final result = await _myCancelableFuture?.cancel();
- setState(() {
- _text = result;
- _isLoading = false;
- });
- }
- ?
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(title: const Text('大前端之旅')),
- body: Center(
- child: _isLoading
- ? const CircularProgressIndicator()
- : Text(
- _text ?? 'Press Start Button',
- style: const TextStyle(fontSize: 28),
- ),
- ),
- // This button is used to trigger _getDate() and _cancelFuture() functions
- // the function is called depends on the _isLoading variable
- floatingActionButton: ElevatedButton(
- onPressed: () => _isLoading ? _cancelFuture() : _getData(),
- child: Text(_isLoading ? 'Cancel' : 'Start'),
- style: ElevatedButton.styleFrom(
- padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
- primary: _isLoading ? Colors.red : Colors.indigo),
- ),
- );
- }
- }
使用 timeout() 方法
这种方法既快速又简单。但是,它不是很灵活。
使用timeout()方法,您可以限制Future的时间(例如 3 秒)。如果 future 及时完成,它的值将被返回。另一方面,如果Future超过限制时间,将执行onTimeout函数:
- Future<T> timeout(
- Duration timeLimit,
- {FutureOr<T> onTimeout()?}
- )
快速示例
创建一个虚拟的Future:
- Future<String?> _myFuture() async {
- await Future.delayed(const Duration(seconds: 10));
- return 'Future completed';
- }
设置超时 3 秒:
- _myFuture().timeout(
- const Duration(seconds: 3),
- onTimeout: () =>
- 'The process took too much time to finish. Please try again later',
- );
将Future转换为流
您可以使用 Future 类的asStream()方法来创建一个包含原始Future结果的流。现在您可以取消对该流的订阅。
快速示例
- // don't forget to import this
- import 'dart:async';
- ?
- // Create a demo future
- Future<dynamic> _loadData() async {
- await Future.delayed(const Duration(seconds: 10));
- return 'Some Data';
- }
- ?
- // a reference to the stream subscription
- // so that we can call _sub.cancel() later
- StreamSubscription<dynamic>? _sub;
- ?
- // convert the future to a stream
- _sub = _loadData().asStream().listen((data) {
- // do something with "data"
- print(data);
- });
- ?
- // cancel the stream subscription
- _sub.cancel();
请注意,这个快速示例仅简要描述了事物的工作原理。您必须对其进行修改以使其可在现有项目中运行。
结论
你已经学会了不止一种方法来取消 Flutter 中的Future。从其中选择一个以在您的应用程序中实现,以使其在处理异步任务时更加健壮和吸引人。
以上就是详解Flutter和Dart取消Future的三种方法的详细内容,更多关于Flutter Dart取消Future的资料请关注w3xue其它相关文章!