Flutter实现ControlExecutor进行多个异步任务执行时监听状态并可指定最后执行的异步并在指定的异步执行完毕后结束executor并回调。

18 篇文章 0 订阅

1.场景

当有多个接口请求时,且接口调用不是同时进行时,而且接口调用有可能时链式的,中间也有可能加入别的逻辑,但是需要在第一个接口调用时打开等待框,在最后一个接口调用完成时关闭等待框类似需求时,可以用到ControlExecutor进行接口执行过程的监听,并可标记最后一个执行的接口,且会等待做了标记的接口完成执行后,关闭执行,并执行onFinish回调。

2.代码

其中executor.dart、group_key.dart、minitor.dart、ke_ex.dart跟上一篇文章CombineExecutor中的一样,请去上一篇文章中去拷贝。

control_executor.dart

import 'package:kq_flutter_widgets/utils/ex/kq_ex.dart';

import 'core/executor.dart';
import 'core/group_key.dart';
import 'core/monitor.dart';

///可控制执行结束时机的执行者。
///主要用于多个接口联级调用或者链式调用等场景Loading框的控制。
///跟CombineExecutor原理类似,只是ControlExecutor可控制,
///不会自动自行完毕,需要用户主动调用stop或者给需要执行完毕的接口添加stop标记。
///可以监听多个接口联级调用、链式调用、多接混合调用出现异常和报错等监听,
///不干涉接口请求逻辑,只监听接口请求的
///成功状态(response.code == ApiResponse.success),失败状态(response.code != ApiResponse.success),
///接口catch后的监听,以及onError监听,例如在调用一系列接口时,
///调用第一个接口之前会回调onStart,
///等调用到接口状态设置了stop=true时的接口时和中间任意一个接口接口异常或失败状态时,
///则会回调onFinish,结束本次执行。
class ControlExecutor {
  ///执行的对象保存
  final Map<GroupKey, List<Monitor>> _monitors = {};

  ///Executor 保存
  final List<Executor> _executors = [];

  final Function(GroupKey key)? onStart;
  final Function(GroupKey key)? onFinish;

  ControlExecutor({this.onStart, this.onFinish});

  ///这里的逻辑跟CombineExecutor不同。
  _executor(GroupKey key) {
    Executor executor = Executor(key);
    if (!_executors.contains(executor)) {
      _executors.add(executor);
      onStart?.call(key);

      executor.start(callback: (key) {
        List<Monitor> combines = _get(key);
        bool flag = false;
        for (Monitor monitor in combines) {
          if (monitor.isError() ||
              monitor.isFinish() && (monitor.getExtra() ?? false)) {
            flag = true;
            break;
          }
        }

        //表示最后一个都已执行完成
        if (flag) {
          executor.stop(callback: (key) {
            onFinish?.call(key);
            _clear(key);
            _executors.remove(executor);
          });
        }
      });
    }
  }

  ///停止,在退出界面时调用
  stop() {
    for (Executor executor in _executors) {
      executor.stop();
    }
    _executors.clear();
    _clearAll();
  }

  ///获取合并执行观察者,
  ///设置到请求逻辑中。
  ///[stop] 是否停止。
  Monitor getMonitor(GroupKey key, {bool? stop}) {
    Monitor monitor = Monitor(extra: stop);
    _addCombine(key, monitor);
    _executor(key);
    return monitor;
  }

  ///新增一个monitor
  _addCombine(GroupKey key, Monitor combine) {
    if (key.isMonitor) {
      if (_monitors.containsKey(key)) {
        List<Monitor>? combines = _monitors[key];
        combines ??= [];
        if (!combines.contains(combine)) {
          combines.add(combine);
        }
      } else {
        _monitors.putIfAbsent(key, () => [combine]);
      }
    }
  }

  List<Monitor> _get(GroupKey key) {
    if (_isEmpty(key)) {
      return [];
    } else {
      return _monitors[key]!;
    }
  }

  ///monitor是否为空
  _isEmpty(GroupKey key) {
    return !_monitors.containsKey(key) || _monitors[key].isNullOrEmpty;
  }

  _clear(GroupKey key) {
    _monitors.remove(key);
  }

  ///清除全部的monitor
  _clearAll() {
    _monitors.clear();
  }
}

///测试
class ControlExecutorTest {
  test() {
    ///创建一个GroupKey,改key可用于一组需要调用的接口上
    GroupKey groupKey = GroupKey();

    ///创建对象
    ControlExecutor executor = ControlExecutor(
      onStart: (key) {
        ///print("开始执行");
      },
      onFinish: (key) {
        if (key == groupKey) {
          ///print("结束执行");
        }
      },
    );

    ///获取monitor 传入到接口调用中
    Monitor monitor1 = executor.getMonitor(groupKey);
    ///获取monitor 传入到接口调用中
    Monitor monitor2 = executor.getMonitor(groupKey);
    ///获取monitor 传入到接口调用中,结束的monitor
    Monitor monitor3 = executor.getMonitor(groupKey, stop: true);

    ///模拟异步对Monitor进行操作
    Future.delayed(const Duration(seconds: 2), () {
      monitor1.onFinish();
    });
    Future.delayed(const Duration(seconds: 3), () {
      monitor2.onFinish();
    });
    Future.delayed(const Duration(seconds: 5), () {
      monitor3.onFinish();
    });

    ///退出界面
    executor.stop();
  }
}

3.使用

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许天成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值