多个异步请求,限制3个并发

362 阅读1分钟
  1. 写法一:简洁易懂
const asyncPool = async (poolLimit, array, iteratorFn) => {
    const resultList = []
    const executing = []
    for (const item of array) {
        const p = Promise.resolve().then(() => {
            return iteratorFn(item, array)
        })
        resultList.push(p)
        if (poolLimit <= array.length) {
            const e = p.then(() => {
                return executing.splice(excuting.indexOf(e), 1)
            })
            executing.push(e)
            if (executing.length >= poolLimit){
                await Promise.race(executing)
            }
        }
    }
    return Promise.all(resultList)
}

const timeout = (i) => new Promise((resolve) => {
    setTimeout(resolve, i, i)
})
const main = async () => {
    const aa = await asyncPool(3, [10,20,30,40,50,60,70,80,90], timeout)
}
main()
  1. 写法二
// 假设请求多张图片
let urls = ['url1', 'url2', 'url3', ... , 'url20']
// 异步请求url,返回结果可以通过.then()获取
function getData(url){
}
function limitLoad(urls, handler, limit) {
    let copyUrls = [].concat(urls) // 拷贝一份urls 
    let promises = copyUrls.splice(0, limit).map((url, index) => {
        return handler(url).then(() => {
            return index
        })
    })
    // reduce()函数中的回调函数,pCollect为初始值也是返回值,通过Promise.resolve()进行初始化
    function getTotalFunc(pCollect, url) {
        return pCollect.then(() => {
            return Promise.race(promises) // 返回已经完成的下标
        }).then((fastestIndex) => {
            promises[fastestIndex] = handler(url).then(() => {
                return fastestIndex
            })
        }).catch((err, url) => {
            console.log(err, url)
        })
    }
    reyurn copyUrls.reduce(getTotalFunc, Promise.resove()).then(() => {
        // 剩余最后三个用all处理
        Promise.all(promises)
    })
}
limitLoad(urls, getData, 3).then((res) => {
    console.log('完成!')
})