SOURCE

// 控制请求并发数
// 设计一个函数,可以限制请求的并发,同时请求结束之后,调用callback函数
// function sendRequest(requestList, limit, callback) {
//   const promises = requestList.slice();
//   const concurrentNum = Math.min(limit,requestList.length);
//   console.log('limit',concurrentNum)
//   let concurrentCount = 0;

//   const picker = () => {
//     if (promises.length > 0 && concurrentCount < limit) {
//       runTask();
//     } else if (promises.length === 0 && concurrentCount === 0) {
//       callback();
//     }
//   }

//   const runner = (task) => {
//     try {
//        task();
//       concurrentCount++;
//     } finally {
//       concurrentCount--;
//       picker();
//     }
//   }
//   const runTask = () => {
//     const task = promises.shift();
//     task && runner(task);
//   }

//   for (let i = 0; i < concurrentNum; i++) {
//     runTask();
//   }
// }

// sendRequest([() => console.log(1),() => console.log(2), () => console.log(3)], 1, () => console.log('回调函数'))


function sendRequest(requestList,limits,callback){

    const promises = requestList.slice() // 取得请求list(浅拷贝一份)

    // 得到开始时,能执行的并发数

    const concurrentNum = Math.min(limits,requestList.length)

    let concurrentCount = 0 // 当前并发数

    // 第一次先跑起可以并发的任务

    const runTaskNeeded = ()=>{

        let i = 0

        // 启动当前能执行的任务
        console.log('i',i, 'concurrentNum', concurrentNum)

        while(i<concurrentNum){

            i++

            runTask()

        }

    }

    // 取出任务并且执行任务

    const runTask = ()=>{

        const task = promises.shift()

        task && runner(task)

    }




    // 执行器

    // 执行任务,同时更新当前并发数

    const runner = async (task)=>{

        try {

            concurrentCount++

            await task()

        } catch (error) {

        }finally{

            // 并发数--

            concurrentCount--
            
            // 捞起下一个任务
            picker()

        }

    }

// 捞起下一个任务

    const picker = ()=>{
        
        // 任务队列里还有任务并且此时还有剩余并发数的时候 执行
        if(concurrentCount < limits && promises.length > 0 ){

            // 继续执行任务

            runTask()

        // 队列为空的时候,并且请求池清空了,就可以执行最后的回调函数了

        }else if(promises.length ==0 && concurrentCount ==0 ){

            // 执行结束

            callback && callback()

        }

    }



    // 入口执行

    runTaskNeeded()

}

sendRequest([() => console.log('request1'),() => console.log('request2'), () => console.log('request3')],4, () => console.log('回调函数'))
console 命令行工具 X clear

                    
>
console