Flutter异步任务管理插件async_queue的使用

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

Flutter异步任务管理插件async_queue的使用

一、简介

async_queue 是一个用于确保您的异步任务列表按顺序执行的Dart包。这意味着所有添加到队列中的任务会一个接一个地被执行,而不是并发执行。

二、特性

  • 普通队列:可以在触发之前将多个作业添加到队列中。
  • 自动启动队列:一旦有任何作业被添加到队列中就会立即开始执行。
  • 监听器支持:可以为队列添加监听器以捕获队列中发生的事件。
  • 失败重试机制:当某个作业失败时可以选择重新尝试执行它。

三、安装和导入库

  1. pubspec.yaml 文件中添加依赖:
dependencies:
    async_queue: ^latest_version # 替换为最新版本号
  1. 在需要使用的地方导入:
import 'package:async_queue/async_queue.dart';

四、使用方法

(一)普通队列

创建一个普通的 AsyncQueue 实例,并向其中添加一些延时打印的任务,最后调用 start() 方法来启动这些任务的执行。

final asyncQ = AsyncQueue();
asyncQ.addJob((_) => Future.delayed(Duration(seconds: 1), () => print("normalQ: 1")));
asyncQ.addJob((_) => Future.delayed(Duration(seconds: 4), () => print("normalQ: 2")));
asyncQ.addJob((_) => Future.delayed(Duration(seconds: 2), () => print("normalQ: 3")));
asyncQ.addJob((_) => Future.delayed(Duration(seconds: 1), () => print("normalQ: 4")));

await asyncQ.start(); // 输出结果依次为 normalQ: 1, normalQ: 2, normalQ: 3, normalQ: 4

(二)自动启动队列

创建一个自动启动的 AsyncQueue 实例(即 AsyncQueue.autoStart()),然后直接向其添加任务,无需显式调用 start() 方法。

final autoAsyncQ = AsyncQueue.autoStart();

autoAsyncQ.addJob((_) => Future.delayed(Duration(seconds: 1), () => print("AutoQ: 1")));
await Future.delayed(Duration(seconds: 6));
autoAsyncQ.addJob((_) => Future.delayed(Duration.zero, () => print("AutoQ: 1.2"))); 
autoAsyncQ.addJob((_) => Future.delayed(Duration.zero, () => print("AutoQ: 1.3"))); 
autoAsyncQ.addJob((_) => Future.delayed(Duration(seconds: 4), () => print("AutoQ: 2"))); 
autoAsyncQ.addJob((_) => Future.delayed(Duration(seconds: 3), () => print("AutoQ: 2.2"))); 
autoAsyncQ.addJob((_) => Future.delayed(Duration(seconds: 2), () => print("AutoQ: 3"))); 
autoAsyncQ.addJob((_) => Future.delayed(Duration(seconds: 1), () => print("AutoQ: 4"))); 

// 输出结果依次为 AutoQ: 1, AutoQ: 1.2, AutoQ: 1.3, AutoQ: 2, AutoQ: 2.2, AutoQ: 3, AutoQ: 4

(三)添加队列监听器

可以通过 addQueueListener() 方法为队列添加监听器,以便能够接收到来自队列内部的通知。

final asyncQ = AsyncQueue();

asyncQ.addQueueListener((event) => print("$event"));

(四)设置任务失败后的重试次数

如果希望在某些情况下让失败的任务再次尝试执行,则可以在添加任务时指定 retryTime 参数。

q.addJob(() async {
  try {
    // 执行具体逻辑...
  } catch (e) {
    q.retry();
  }
}, retryTime: 3); // 默认值为1次重试

五、Flutter中的应用场景

此插件非常适合处理那些相互关联且需要按特定顺序完成的异步请求场景,比如:

  • 确保一个组件发起的请求必须等待另一个组件的请求完成后才能开始。
  • 防止短时间内前端频繁发送大量请求给后端服务器造成混乱。

下面是一个简单的例子,展示了如何在一个Flutter应用中使用 async_queue 来管理按钮点击触发的不同时间间隔的任务。

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final aQ = AsyncQueue.autoStart();
    
    return Scaffold(
      appBar: AppBar(title: Text('Async Queue Demo')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          ElevatedButton(
            onPressed: () async {
              aQ.addJob((_) => Future.delayed(Duration(seconds: 2), () => print("job1 ")));
            },
            child: Text('job1'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () async {
              aQ.addJob((_) => Future.delayed(Duration(seconds: 4), () => print("job2")));
            },
            child: Text('job2'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () async {
              aQ.addJob((_) => Future.delayed(Duration(seconds: 1), () => print("job3")));
            },
            child: Text('job3'),
          ),
        ],
      ),
    );
  }
}

六、反馈与贡献

如果您发现了任何问题或者有新的功能需求,请随时前往 GitHub 提交issue。


更多关于Flutter异步任务管理插件async_queue的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter异步任务管理插件async_queue的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,async_queue 是一个用于管理异步任务的插件。它允许你以队列的方式处理异步操作,确保任务按顺序执行,避免了并发问题。以下是一个使用 async_queue 的代码示例,展示了如何设置和使用这个插件来管理异步任务。

首先,你需要在 pubspec.yaml 文件中添加 async_queue 依赖:

dependencies:
  flutter:
    sdk: flutter
  async_queue: ^x.y.z  # 请替换为最新版本号

然后,运行 flutter pub get 来安装依赖。

接下来,我们来看一个具体的代码示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Async Queue Example'),
        ),
        body: AsyncQueueExample(),
      ),
    );
  }
}

class AsyncQueueExample extends StatefulWidget {
  @override
  _AsyncQueueExampleState createState() => _AsyncQueueExampleState();
}

class _AsyncQueueExampleState extends State<AsyncQueueExample> {
  final AsyncQueue<void> _queue = AsyncQueue<void>();
  bool _isRunning = false;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: _addTask,
            child: Text('Add Task'),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _startQueue,
            child: Text('Start Queue'),
            enabled: !_isRunning,
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _stopQueue,
            child: Text('Stop Queue'),
            enabled: _isRunning,
          ),
        ],
      ),
    );
  }

  void _addTask() {
    _queue.enqueue(() async {
      // 模拟异步任务,例如网络请求或文件读写
      await Future.delayed(Duration(seconds: 2));
      print('Task completed');
    });
  }

  void _startQueue() {
    setState(() {
      _isRunning = true;
    });
    _queue.processQueue().catchError((error) {
      print('Error processing queue: $error');
      setState(() {
        _isRunning = false;
      });
    }).whenComplete(() {
      setState(() {
        _isRunning = false;
      });
    });
  }

  void _stopQueue() {
    // 注意:这个示例中的队列不支持中途停止,这里的停止按钮只是为了演示状态管理
    // 真实应用中,你可能需要设计更复杂的状态和队列管理机制来实现中途停止功能
    _queue.cancelAll(); // 取消所有未执行的任务,但注意这个操作取决于具体的队列实现
    setState(() {
      _isRunning = false;
    });
  }
}

解释

  1. 依赖管理:在 pubspec.yaml 文件中添加 async_queue 依赖。
  2. 创建队列:在 _AsyncQueueExampleState 类中,我们创建了一个 AsyncQueue<void> 实例 _queue
  3. 添加任务_addTask 方法用于向队列中添加异步任务。每个任务是一个返回 Future<void> 的函数。
  4. 启动队列_startQueue 方法用于启动队列处理。这里我们调用 _queue.processQueue() 来按顺序执行队列中的所有任务。使用 setState 来更新按钮的启用状态。
  5. 停止队列_stopQueue 方法尝试停止队列处理。然而,由于 async_queue 插件本身可能不支持直接停止处理中的队列,这里只是演示了状态管理。在真实应用中,你可能需要设计更复杂的状态和队列管理机制。

请注意,这个示例代码是基于 async_queue 插件的通用用法,但具体实现可能因插件版本和API变化而有所不同。因此,在实际使用时,请查阅最新的插件文档和API参考。

回到顶部