【JS】并发控制

需求

  • 控制网络请求并发数
  • 控制并发按顺序返回结果


/**
* 控制并发
* @param {Function} fn 逻辑处理函数
* @param {Array} arr 发送的数据
* @param {Number} [max=3] 并发数 默认3
* @param {Number} [order=false] 按顺序返回执行结果 默认false
* @param {Number} [retry=1] 重试次数 默认1
* @returns {Promise} 返回Promise
*/
const reqPool = (fn, arr, max = 3, order = false, retry = 1) => {
    let reqList        = [...arr],                                        //不改变arr
        resData        = order ? Array(reqList.length).fill(0, 0) : [],   //  order = true 填充返回的数据
        curRuningCount = 0,                                               //限制内的第n个并发 
        runedCount     = 0,                                               //已执行的数量                         
        runingIndex    = 0;                                               //当前执行下标                       

    return new Promise(res => {
        const run = _ => {
            while (curRuningCount < max && reqList.length) {
                curRuningCount++
                const chunk = reqList.shift();
                (i => {
                    /**
                 * 当前重试次数 
                 */
                    let _retry = 0
                    const add = (i2, data) => fn(data)
                        .then(r => {
                            runedCount++
                            order ? resData[i2] = r : resData.push(r)
                        })
                        .catch(err => {
                            _retry++
                            const repMore = _retry > retry
                            if (!repMore) {
                                add(i2, data)
                                console.log(data, '重试' + _retry + '次');
                            } else {
                                order ? resData[i2] = err : resData.push(err)
                                runedCount++
                            }
                        })
                        .finally(_ => {
                            curRuningCount--
                            if (runedCount === arr.length) res(resData)
                            run()
                        });
                    add(i, chunk)
                })(runingIndex++)
            }
        }
        run()
    })
}

// 请求配置 | 请求体
const chunks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

/**
* 逻辑处理函数 | 如:发起请求
* @param {Object} chunk
* @returns {Promise} 
*/
const req = chunk => new Promise((res, rej) => setTimeout(_ => Math.random() > .8 ? rej('失败----' + chunk) : res('结果' + chunk), Math.random() * 100 + 100))

reqPool(req, chunks, 3, true).then(res => console.log(res))

运行图

在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值