如何控制promise并发数

思路:

  1. 先发送3个,3个中哪个先响应了,立即发送第4个,第4个和前面没响应的两个中哪个先响应了,立即发送第5个,直到10个发送完
  2. 利用Promise.race()获取最先响应的请求
  3. 利用array.reduce实现队列执行
function sleep(time) {
    return new Promise(resolve => {
        setTimeout(resolve, time)
    })
}
function loadData(url) {
    return new Promise(async (resolve, reject) => {
        await sleep(url.time)
        resolve(url.info)
    })
}
const urls =[
    {info:'1', time:2000},
    {info:'2', time:2000},
    {info:'3', time:2000},
    {info:'4', time:2000},
    {info:'5', time:3000},
    {info:'6', time:1000},
    {info:'7', time:2000},
    {info:'8', time:2000},
    {info:'9', time:3000},
    {info:'10', time:1000}
]
// 先发送3个,3个中哪个先响应了,立即发送第4个,
// 第4个和前面没响应的两个中哪个先响应了,立即发送第5个,直到10个发送完
function limitLoad(urls, handler, limit) {
    // 将数组拷贝一份
    let queue = [].concat(urls)
    let promises = []
    // 首先并发3个
    promises = queue.splice(0, limit).map((url,index) => {
        return handler(url).then(res => {
            console.log(index, url);
            // 用Promise.race找到先影响的脚标,下个请求插入到这个脚标位置来请求
            return index
        })
    })
    // 剩下的数组以队列的形式来执行
    queue.reduce((p, url) => {
        return p.then(index => {
            promises[index] = handler(url).then(() => {
                console.log(index, url);
                return index // 继续返回脚标
            })
            return Promise.race(promises)
        })
    }, Promise.race(promises))
}
limitLoad(urls, loadData, 3)