IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 简单的前端任务队列 -> 正文阅读

[JavaScript知识库]简单的前端任务队列

背景
在开发中,我们会遇到一些使用多个异步请求但返回数据需要按序的问题,如前端导出、多个文件上传,你可能会想到使用结合并发限制下分组处理使用Promise.all,虽然说这种方式可以提高请求的速度,但终归的得等到所有响应回来后才可进入下一个分组。这时候我们就可以用结合并发数,结合队列的特点让请求有序发出。
介绍
结合网上其他大佬的做法实现了一些改造,接下来让我们来介绍一下如何实现一个在限制最大同时并发数同时并在请求失败时可以重发的通用请求并发队列:

export default class RequestQueue {
    constructor(maxLimit = 5, retryLimit = 2) {
        //最大同时请求数
        this.maxLimit = maxLimit;
        //尝试总数
        this.retryLimit = retryLimit;

        //等待执行的任务队列
        this.taskQueue = [];
        //当前请求并发数
        this.currentRequestCount = 0;

		//当前请求成功数
        this.doneCount = 0;
    }


	/*
     *@functionName:  exec
     *@params1: request(异步请求 调用测传入 需为Promise实例)
     *@params2: callBack 回调函数 一般用于前端progress统计当前进度
    */
    async exec(request, callBack = () => {}) {
        let result = [];
        
        // 并发限制
        if (this.currentRequestCount >= this.maxLimit) {
            await this.pause(); // 暂停执行 入队
        }
        
        // 执行队列长度+1
        this.currentRequestCount++;

        // 设置队列当前任务的执行次数
        for (let retryCount = this.retryLimit; retryCount > 0; retryCount--) {
            let done = false;
            try {
            	//request传入的必须是一个promise实例
                result = await request();
                done = true;
                this.doneCount++;
                return Promise.resolve(result);
            } catch (error) {
                // 最后一次重试失败时停止重试,返回报错
                if (retryCount === 1) {
                    done = true;
                    return Promise.reject(error); // 错误只会抛出一次
                }
            } finally {
                if (done) {
                    callBack(this.doneCount);
                    this.currentRequestCount--;
                    this.next(); //任务队列首部出队
                }
            }
        }
    }

    next() {
        if (this.taskQueue.length <= 0) return;
        const resolve = this.taskQueue.shift();
        resolve(); // 取出任务队列首部执行
    }

    pause() {
        // 入队 将promise对象入队 不rosolve之前无法执行下个任务
        return new Promise((resolve) => this.taskQueue.push(resolve));
    }
}

使用方法:

const request = () => {
    return new Promise((resolve, reject) => {
     setTimeout(() => { resolve() }, 1000)
   })
};

let requestList = [];
const instance = new RequestQueue();
const callBack = () => {}


for (let i = 0; i < 100; i++ ) {
  requestList.push(instance.exec(request,callBack)
    .catch(err => {
        // 这里是否catch(err)取决于是否允许某个任务失败时,其他任务继续执行
       console.log(err)
    })
  )
}

Promise.all(requestList).then((res) => {
	//如需获取数据
	console.log(res.falt(1))
})
  .catch(err => console.log(err)) 

结语
感谢你的观看,这种写法可能还存在问题,仅供学习。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:20:01  更:2022-03-08 22:23:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:59:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码