SOURCE

// 并发请求函数,最多maxNum并行请求
const concurrencyRequest = (urls, maxNum) => {
    return new Promise((resolve) => {
        if (urls.length === 0) {
            resolve([]);
            return;
        }
        const results = [];
        let index = 0; // 下一个请求的下标
        let count = 0; // 当前请求完成的数量

        // maxNum和urls.length取最小进行调用
        const times = Math.min(maxNum, urls.length);
        for(let i = 0; i < times; i++) {
            request();
        }

        // 发送请求
        async function request() {
            if (index === urls.length) return;
            const i = index; // 保存序号,使result和urls相对应
            const url = urls[index];
            index++;
            console.log(url);
            try {
                // 阻塞后面代码 会在这等待resp
                const resp = await fetch(url);
                // resp 加入到results
                results[i] = resp;
            } catch (err) {
                // err 加入到results
                results[i] = err;
            } finally {
                // 请求完成
                count++;
                // 判断是否所有的请求都已完成
                if (count === urls.length) {
                    console.log('完成了');
                    resolve(results);
                }else{
                    request();
                }
                
            }
        }
    })
}

await concurrencyRequest()


// 解法2


// // 最大允许三个请求并发,有一个返回后可以请求下一个
const request = createRequest(3);
// 假设调了五个 只有三个可以一开始并发进行
for (var i = 0; i < 5; i++) {
    request('/api').then((d) => console.log(d))
}

// ======>
// ====>
// ========>
//      =====>
//        ======>
//
function createRequest(count) {
    let num = 0
    let requestPromise = []
    return async function  request(url) {
        // 如果当前的调用数 小于count 那么直接调用
        num++
        if(num < count) {
            return startRequest()
        }else{
            await Promise.race([requestPromise])

            return startRequest()
        }

        function startRequest(){
            let curPromise = new Promise((resolve, reject) => {
                fetch(url).then(()=>{
                    resolve("success")
                    num--
                },()=>{
                    reject("failed")
                    num--
                })
            })
            // 最关键的一步 利用链式回调消除自己
const e = curPromise.then(()=>{
    requestPromise.splice(requestPromise.indexOf(e),1)
},()=>{
    requestPromise.splice(requestPromise.indexOf(e),1)
})
            requestPromise.push(e)
            return curPromise
        }
    }
}
console 命令行工具 X clear

                    
>
console