js 多个异步 的并发控制

  今天在群里看到一个人发的面试题:  

1,请实现如下的函数,可以批量请求数据,所有的URL地址在urls参数中,同时可以通过max参数 控制请求的并发度。当所有的请求结束后,需要执行callback回调。发请求的函数可以直接使用fetch。

function sendRequest (urls: string[], max: number, callback: () => void) {

}

    fetch 函数返回的是一个promise,promise对象在实例化的时候就已经开始执行了。

    

function sendRequest(arr, max, callback) {
        let fetchArr = [],  // 存储并发max的promise数组
            i = 0;

        function toFetch() {
            if (i === arr.length) {   // 所有的都处理完了, 返回一个resolve
                return Promise.resolve();
            }

            let one = fetch(arr[i++]); // 取出第i个url, 放入fetch里面 , 每取一次i++
            one.then( () => {fetchArr.splice(fetchArr.indexOf(one), 1)}); // 当promise执行完毕后,从数组删除
            fetchArr.push(one);  //将当前的promise存入并发数组中       其实将这个push放到上一行会更好理解,那样就是我们同步的思维顺序,先push进去,再等promise执行完了之后再删除。  但由于then是异步的,所以怎么放都可以。

            let p = Promise.resolve();
            if (fetchArr.length >= max) {     // 当并行数量达到最大后, 用race比较 第一个完成的, 然后再调用一下函数自身。
                p = Promise.race(fetchArr);
            }
            return p.then(() => toFetch());
        }
        
        // arr循环完后, 现在fetchArr里面剩下最后max个promise对象, 使用all等待所有的都完成之后执行callback
        toFetch().then(() => Promise.all(fetchArr)).then(() => {
            callback();
        })
}

  

原文地址:https://www.cnblogs.com/wjyz/p/10541581.html