Flutter任务队列管理插件serial_queue的使用

Flutter任务队列管理插件serial_queue的使用

特性

将并发业务流程转换为每个业务流程的串行顺序执行。

开始使用

安装包:

# 在 pubspec.yaml 文件中添加依赖
dependencies:
  serial_queue: ^版本号

使用方法

示例1

import 'package:serial_queue/serial_queue.dart';
import 'package:serial_queue/sleep.dart';

int i = 0;

void main() async {
  SerialQueue queue = SerialQueue()..startQueue();

  Future.delayed(const Duration(milliseconds: 20), () async {
    Task<int, List<int>> addTask = Task.create(taskHandler: add, params: [1, 2, 3, 4, 5, 6, 7, 8, 9]);
    queue.addTask(addTask);
    var sum = await addTask.future;
  });

  Future.delayed(const Duration(milliseconds: 20), () async {
    Task<void, String> incrementTask = Task.create(taskHandler: increment, params: 'D');
    queue.addTask(incrementTask);
    await incrementTask.future;
  });

  Future.delayed(const Duration(milliseconds: 20), () async {
    Task<void, String?> showTask = Task.create(taskHandler: show, params: 'text content');
    queue.addTask(showTask);
    await showTask.future;
  });
  await sleep(1000);
}

int add({List<int>? params})  {
  var sum = params!.reduce((value, element) => value + element);
  return sum;
}

void show({String? params}) async {
  print('$params');
  return;
}

Future<int> increment({String? params}) async {
  int a = i;
  await sleep(3);
  a++;
  i = a;
  print('正在处理 increment 任务----$params--$i');
  return i;
}

示例2

import 'package:flutter_test/flutter_test.dart';
import 'package:serial_queue/serial_queue.dart';
import 'package:serial_queue/sleep.dart';

/// 100个人在5台atm机上存钱
void main() async {
  bool useQueue = false;
  Bank bank = Bank(name: 'ABC', useQueue: useQueue);

  var team1 = bank.persons.sublist(0, 20);
  var team2 = bank.persons.sublist(20, 40);
  var team3 = bank.persons.sublist(40, 60);
  var team4 = bank.persons.sublist(60, 80);
  var team5 = bank.persons.sublist(80, 100);

  Future.delayed(const Duration(), () async {
    for (var person in team1) {
      await bank.atms[0]?.deposit(person!.accountNo, 100);
      await sleep(30);
    }
  });
  Future.delayed(const Duration(), () async {
    for (var person in team2) {
      await bank.atms[1]?.deposit(person!.accountNo, 100);
      await sleep(2);
    }
  });
  Future.delayed(const Duration(), () async {
    for (var person in team3) {
      await bank.atms[2]?.deposit(person!.accountNo, 100);
      await sleep(2);
    }
  });
  Future.delayed(const Duration(), () async {
    for (var person in team4) {
      await bank.atms[3]?.deposit(person!.accountNo, 100);
      await sleep(2);
    }
  });
  Future.delayed(const Duration(), () async {
    for (var person in team5) {
      await bank.atms[4]?.deposit(person!.accountNo, 100);
      await sleep(2);
    }
  });
  // Future.delayed(const Duration(milliseconds: 200), () async {
  //   bank.atms[0]!.hasError = true;
  //   await sleep(200);
  //   bank.atms[0]!.hasError = false;
  // });
  await sleep(3000);
  await bank.close();
}

///
class Person {
  Person({required this.accountNo});
  String accountNo;
  double money = 0;
  void look() {}
}

///
class ATM {
  Bank bank;
  String id;
  double money = 0;
  bool hasError = false;

  ATM({required this.bank, required this.id});

  Future<bool> deposit(String accountNo, double money) async {
    if (hasError) {
      return await bank.atmTimeout();
    }
    return await bank.atmDeposit(id, accountNo, money);
  }

  void look() {
    print('ATM id:$id   money=$money');
  }
}

///
class Bank {
  double total = 0;
  var persons = <Person?>[];
  var atms = <ATM?>[];
  String name;
  bool useQueue = false;
  late SerialQueue queue;
  int orderId = 0;

  ///
  Bank({required this.name, this.useQueue = false}) {
    queue = SerialQueue(log: true)..startQueue();
    for (int i = 0; i < 5; i++) {
      atms.add(ATM(bank: this, id: 'id-$i'));
    }
    for (int i = 0; i < 100; i++) {
      persons.add(Person(accountNo: 'N@$i'));
    }
  }

  Future<bool> atmTimeout() {
    var task = Task<bool, String>.create(
      taskHandler: ({String? params}) {
        print(params);
        return false;
      },
      params: '-----------》 ATM故障!!!',
    );
    queue.addTask(task);
    return task.future.onError((error, stackTrace){
      print('$error');
      return false;
    });
  }

  ///
  Future<bool> atmDeposit(String fromAtmId, String accountNo, double money) async {
    if (useQueue) {
      var task = Task<bool, DepositInfo>.create(taskHandler: _atmDeposit, params: DepositInfo(fromAtmId: fromAtmId, accountNo: accountNo, money: money));
      queue.addTask(task);
      var r = await task.future.onError((error, stackTrace){
        print('$error');
        return false;
      });
      return r;
    } else {
      return _atmDeposit(params: DepositInfo(fromAtmId: fromAtmId, accountNo: accountNo, money: money));
    }
  }

  ///
  Future<bool> _atmDeposit({DepositInfo? params}) async {
    print('orderId:${orderId++}     fromAtmId:${params!.fromAtmId}  ${params.accountNo}  ${params.money}');
    await sleep(2);
    var atm = atms.firstWhere((atm) => atm?.id == params.fromAtmId, orElse: () => null);
    if (atm == null) {
      return false;
    }
    var person = persons.firstWhere((p) => p?.accountNo == params.accountNo, orElse: () => null);
    if (person == null) {
      return false;
    }
    double t = total;
    double atmT = atm.money;
    await sleep(2);
    person.money += params.money;
    atmT += params.money;
    t += params.money;
    await sleep(1);
    total = t;
    atm.money = atmT;
    return true;
  }

  ///
  void look() {
    print('Bank name:$name   total=$total');
    for (var atm in atms) {
      atm!.look();
    }
    for (var p in persons) {
      p!.look();
    }
  }

  Future<void> close() async {
    await queue.dispose(() {
      print('---------------------银行结算信息---------------------');
      look();
    });
  }
}

class DepositInfo {
  String fromAtmId;
  String accountNo;
  double money;

  DepositInfo({required this.fromAtmId, required this.accountNo, required this.money});
}

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

1 回复

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


serial_queue 是一个用于 Flutter 的简单任务队列管理插件,它可以帮助你按顺序执行异步任务。这在某些需要确保任务按顺序执行的场景中非常有用,例如在处理网络请求、文件操作或数据库操作时。

安装

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

dependencies:
  serial_queue: ^1.0.0

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

基本用法

serial_queue 的核心是 SerialQueue 类,它允许你按顺序添加和执行任务。

1. 创建队列

你可以通过创建一个 SerialQueue 实例来管理任务队列:

import 'package:serial_queue/serial_queue.dart';

final serialQueue = SerialQueue();

2. 添加任务

你可以通过 add 方法向队列中添加任务。任务是一个返回 Future 的函数:

serialQueue.add(() async {
  print('Task 1 started');
  await Future.delayed(Duration(seconds: 2));
  print('Task 1 completed');
});

serialQueue.add(() async {
  print('Task 2 started');
  await Future.delayed(Duration(seconds: 1));
  print('Task 2 completed');
});

3. 等待任务完成

你可以使用 onComplete 方法来等待队列中的所有任务完成:

serialQueue.onComplete.then((_) {
  print('All tasks completed');
});

4. 取消任务

你可以使用 cancel 方法来取消队列中的所有任务:

serialQueue.cancel();

示例

以下是一个完整的示例,展示了如何使用 serial_queue 来按顺序执行任务:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Serial Queue Example')),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              runSerialQueueExample();
            },
            child: Text('Run Example'),
          ),
        ),
      ),
    );
  }
}

void runSerialQueueExample() async {
  final serialQueue = SerialQueue();

  serialQueue.add(() async {
    print('Task 1 started');
    await Future.delayed(Duration(seconds: 2));
    print('Task 1 completed');
  });

  serialQueue.add(() async {
    print('Task 2 started');
    await Future.delayed(Duration(seconds: 1));
    print('Task 2 completed');
  });

  serialQueue.add(() async {
    print('Task 3 started');
    await Future.delayed(Duration(seconds: 3));
    print('Task 3 completed');
  });

  await serialQueue.onComplete;
  print('All tasks completed');
}
回到顶部