当前位置: 首页 > news >正文

React-异步队列执行方法useSyncQueue

1. 完整代码

import React, { useEffect, useRef } from 'react';
import { useDebounceFn } from "ahooks";
// 队列任务类型
interface QueueTask {
  id: number | string;
  execute: () => PromiseLike<any>;
}
// 异步队列执行方法
function useSyncQueue(params:any) {
  const { limit = 3 } = params||{};

  const queue = useRef<QueueTask[]>([]);

  // 任务执行完成后的回调函数
  let overCallback = useRef<() => void>();
  // 等待所有任务执行完成的Promise
  const awaitExeOver = () => {
    return new Promise<void>((resolve, reject) => {
      if (queue.current.length === 0 && executingNum.current === 0) {
        resolve();
      }
      overCallback.current = () => {
        resolve();
        overCallback.current = undefined;
      }
    })
  };

  // 添加任务
  const addTask = (task: QueueTask | QueueTask[]) => {
    if (Array.isArray(task)) {
      queue.current = queue.current.concat(task);
    } else {
      queue.current.push(task);
    }
    executeTask();
  };

  // 执行中的任务数量
  const executingNum = useRef(0);
  // 执行队列中的任务
  const { run: executeTask } = useDebounceFn(() => {
    // 凑齐同时执行的最大任务数量
    while (executingNum.current < limit && queue.current.length > 0) {
      const task = queue.current.shift(); // 获取队列中的第一个任务
      if (task) {
        executingNum.current += 1; // 更新执行中的任务数量
        task.execute().then(res => {
          executingNum.current -= 1; // 更新执行中的任务数量
          console.log('执行任务', task.id, '执行结果', res, '当前执行中的任务数量', executingNum.current, '当前队列长度', queue.current.length);

          if (queue.current.length === 0 && executingNum.current === 0) {
            // 所有任务执行完成
            overCallback.current?.();
          } else {
            // 继续执行队列中的任务
            executeTask();
          }
        })
      }
    }
  }, { wait: 300 });

  return { addTask, awaitExeOver };
}

2. 使用方式:

useSyncQueue返回两个方法:

  • addTask添加任务;
    可单个添加,可数组添加;
    任务对象QueueTask由唯一ID和获取异步Promise的execute方法组成;
    添加任务后,会自动执行队列任务,直到队列为空
  • awaitExeOver等待任务全部执行完;
    要在添加过任务之后调用awaitExeOver方法;
    执行awaitExeOver方法,才会创建回调方法overCallback;
    队列为空时,执行overCallback,awaitExeOver方法等待结束;

相关文章:

  • MySql的in和join对比谁更高效
  • JVM_八股场景题
  • 【含文档+PPT+源码】Python爬虫人口老龄化大数据分析平台的设计与实现
  • Kubernetes开发环境minikube | 开发部署apache tomcat web集群应用
  • VUE2脚手架的下载与安装
  • 【含文档+PPT+源码】基于Python爬虫二手房价格预测与可视化系统的设计与实现
  • php虚拟站点提示No input file specified时的问题及权限处理方法
  • Web3 的隐私保护机制:如何保障个人数据安全
  • 【今日EDA行业分析】2025年3月8日
  • http协议的三次握手机制
  • Spring源码探析(一):SpringApplication构造函数核心逻辑
  • 工程化与框架系列(27)--前端音视频处理
  • 用OpenCV写个视频播放器可还行?(C++版)
  • MySQL知识点(第一部分)
  • 深度学习|自监督学习新星:DINO 解析与实践指南
  • 请谈谈 HTTP 中的安全策略,如何防范常见的Web攻击(如XSS、CSRF)?
  • 机器人匹诺曹机制,真话假话平衡机制
  • rpc和proto
  • C++ 算法竞赛STL以及常见模板
  • VMware workstation Pro 17 官网下载教程/安装包
  • 2人恶意传播刘国梁谣言被处罚,媒体:以法律利剑劈谣斩邪,加快推进依法治体
  • 盐城经济技术开发区党工委书记王旭东接受纪律审查和监察调查
  • 上海国际珠宝时尚功能区未来三年如何建设?六大行动将开展
  • 英德宣布开发射程超2000公里导弹,以防务合作加强安全、促进经济
  • 浙江省台州市政协原副主席林虹被“双开”
  • 外交部:国际社会广泛理解和支持中方不同意台参加世卫大会的决定