编辑代码

// 请求多个地址,限制并发数量 
const urls =  [
    {
        link: 'bytedance.com',
        time: 1000
    },
    {
        link: 'tencent.com',
        time: 3000
    },
    {
        link: 'alibaba.com',
        time: 2000
    },
    {
        link: 'microsoft.com',
        time: 1000
    },
    {
        link: 'apple.com',
        time: 4000
    },
    {
        link: 'hulu.com',
        time: 3000
    },
    {
        link: 'amazon.com',
        time: 2000
    }
] // 请求地址

// 辅助函数,生成模拟请求的promise
const request = url => {
    return new Promise(resolve => {
        console.log(`开始执行: ${url.link}-${url.time}`)
        setTimeout(() => {
            resolve(url)
            // resolve(`完成执行: ${url.link}-${url.time}: `)
        }, url.time)
    })
}

// 编写:并发请求函数
function taskConcurrentExec(list, concurrentNum) {
    let num = 0 // 已完成任务数量
    const queue = []
    const result = []
    return new Promise(async (resolve, reject) => {
        for(let i=0;i<list.length;i++) {
            const task = request(list[i])
            task.then(res => {
                // 任务执行完,将当前任务从队列中剔除
                console.log(`%c完成执行: ${res.link}-${res.time}`,'color: red;')
                queue.splice(queue.indexOf(task), 1)
                result[i] = res
                num++

                if(num === list.length){
                    resolve(result)
                }
            })
            queue.push(task)
           if(queue.length === concurrentNum) { // 并行执行
               await Promise.race(queue)
           }
        }
    })
}

const startTime = Date.now()
taskConcurrentExec(urls, 3).then(res => {
  console.log(`全部执行完成,耗时${Date.now() - startTime}ms`)
  console.log(res)
})