07.多路任务复用的算法实现
1 什么是"多路任务复用"?
在多次调用同一个任务时,且这个任务耗时较长。这样一来每调用一次任务就要生成一个任务,然后等待。这样就会形成多个任务在执行。且要从头开始等待任务的返回结果。 这样一来不仅会有大量重任务被创建,且也不能节省时间。

既然多将创建任务的都是同一个任务,那么为什么不复用同一个任务呢?可以只创建一个任务,而然后任务都给阻塞住,等有任务返回结果后,再把结果返回给阻塞的 调用。这样就可以节省资源的开销和等待的时间。

2 代码实现
multiplex_task_pool.dart
import 'dart:async';
/// 多路任务复用池
class MultiplexTaskPool {
  List<Function<T>({required bool isResult, T? result, Exception? error})> callbackList = [];
  static MultiplexTaskPool builder() {
    return MultiplexTaskPool();
  }
  Future<T> start<T>(Future<T> Function() callback) {
    Completer<T> completer = Completer();
    callbackList.add(
      <B>({required bool isResult, B? result, Exception? error}) {
        if (isResult) {
          error != null ? completer.completeError(error) : completer.complete(result as T);
        } else {
            callback().then((finalResult) {
              for (var i = 0; i < callbackList.length; i++) {
                callbackList[i](isResult: true, result: finalResult);
              }
              callbackList.clear();
            }).catchError((e, track) {
              print(e);
              print(track);
              for(var callback in callbackList) {
                callback(isResult: true, result: null, error: e);
              }
              callbackList.clear();
            });
        }
      },
    );
    if (callbackList.length == 1) {
      callbackList[0](isResult: false);
    }
    return completer.future;
  }
}
代码的思路是,把任务的逻辑通过回调方式传入进来,并把任务注册到任务池中,然后调用任务。而后面也会创建相同的任务时,也是把任务加入到任务池中,但 由于已经调用过一次了,有任务有处理了,所以不创建相同的任务了,等任务一结束,就解放阻塞,向各个任务池中的回调中返回任务的结果。然后清空任务池。
3 使用示例
使用示例
class RegisterService  {
  static List<Function({required bool isResult, bool? result})> callbackList = [];
  static MultiplexTaskPool hasRegisterTaskPool = MultiplexTaskPool.builder(); // 多路任务复用池
  
  Future<bool> hasRegister() async {
    return await hasRegisterTaskPool.start<bool>(() async {
      await Future.delayed(const Duration(seconds: 4));
      print('hello! 有人吗?');
      reutrn true;
    });
  }
  /// 并发执行
  void run() async {
      final results = await Future.wait([
        hasRegister(),
        hasRegister(),
        hasRegister(),
        hasRegister(),
      ]);
  }
}
最终执行的打印结果
$ hello! 有人吗?