Flutter未来功能扩展插件future_ext的使用

Flutter未来功能扩展插件future_ext的使用

在本篇文章中,我们将探讨如何使用 future_ext 插件来增强 Flutter 应用中的异步操作。future_ext 提供了一些有用的扩展,比如 ControllableFuture,它允许你取消正在进行的 Future。

ControllableFuture

ControllableFuture 允许你在执行异步操作时取消该操作。

final controllable = ControllableFuture(() async {
  /// 一些异步代码
}, onCancel: () {
  // 返回一个替代值
});

// 等待 Future 完成
await controllable.future;

// 取消 Future
controllable.cancel();

使用场景

假设你正在开发一个下载文件的功能,并希望在用户取消下载时能够立即停止下载并释放资源。

import 'package:flutter/material.dart';
import 'package:future_ext/future_ext.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ControllableFuture 示例'),
        ),
        body: Center(
          child: DownloadButton(),
        ),
      ),
    );
  }
}

class DownloadButton extends StatefulWidget {
  [@override](/user/override)
  _DownloadButtonState createState() => _DownloadButtonState();
}

class _DownloadButtonState extends State<DownloadButton> {
  Future<void>? _downloadFuture;
  bool _isDownloading = false;

  void _startDownload() async {
    setState(() {
      _isDownloading = true;
    });

    final controllable = ControllableFuture<void>(() async {
      /// 模拟下载过程
      await Future.delayed(Duration(seconds: 5));
    }, onCancel: () {
      // 取消下载时返回一个替代值
      return Future.value(null);
    });

    try {
      await controllable.future;
    } catch (e) {
      print("下载被取消");
    }

    setState(() {
      _isDownloading = false;
    });
  }

  void _cancelDownload() {
    if (_downloadFuture != null) {
      _downloadFuture!.cancel();
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: !_isDownloading ? _startDownload : null,
          child: Text(_isDownloading ? '下载中...' : '开始下载'),
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: _isDownloading ? _cancelDownload : null,
          child: Text('取消下载'),
        ),
      ],
    );
  }
}

更多关于Flutter未来功能扩展插件future_ext的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter未来功能扩展插件future_ext的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


future_ext 是一个用于 Flutter 的扩展插件,旨在提供一些便捷的功能来增强 Dart 的 Future 类的功能。虽然目前没有官方维护的 future_ext 插件,但你可以通过自定义扩展方法来增强 Future 的功能。以下是一个简单的示例,展示如何使用 Dart 的扩展方法来为 Future 添加一些实用功能。

1. 创建扩展方法

首先,你可以创建一个 Dart 文件来定义你的扩展方法。例如,创建一个名为 future_extensions.dart 的文件:

extension FutureExtensions<T> on Future<T> {
  /// 添加一个超时机制,如果 Future 在指定时间内未完成,则抛出 TimeoutException
  Future<T> timeoutAfter(Duration duration) async {
    return await this.timeout(duration);
  }

  /// 添加一个重试机制,如果 Future 失败,则重试指定次数
  Future<T> retry(int retries, {Duration? delay}) async {
    for (int i = 0; i < retries; i++) {
      try {
        return await this;
      } catch (e) {
        if (i == retries - 1) rethrow;
        if (delay != null) await Future.delayed(delay);
      }
    }
    throw StateError('Retry failed');
  }

  /// 添加一个回调函数,当 Future 完成时执行
  Future<T> onComplete(void Function(T) callback) async {
    final result = await this;
    callback(result);
    return result;
  }

  /// 添加一个回调函数,当 Future 失败时执行
  Future<T> onError(void Function(Object, StackTrace) callback) async {
    try {
      return await this;
    } catch (e, stackTrace) {
      callback(e, stackTrace);
      rethrow;
    }
  }
}

2. 使用扩展方法

在你的 Flutter 项目中,你可以导入这个文件并使用这些扩展方法。例如:

import 'future_extensions.dart';

void main() async {
  try {
    final result = await fetchData()
        .timeoutAfter(Duration(seconds: 5))
        .retry(3)
        .onComplete((data) {
          print('Data fetched successfully: $data');
        })
        .onError((error, stackTrace) {
          print('Error fetching data: $error');
        });

    print('Final result: $result');
  } catch (e) {
    print('Failed to fetch data: $e');
  }
}

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  // 模拟数据获取
  return 'Data';
}
回到顶部