asyncPool应用场景

一个不太常见的极端场景,当我们为了某个操作需要发生异步请求的时候,等待所有异步请求都完成时进行某些操作。这个时候我们不在简简单单的发送 1 - 2 个请求而是 5 - 10个(其实极端场景式 很多很多个请求,这个打个比喻更容易理解)。 通常情况下我们通过 promise.all 可以保证多个请求完成后进行操作,等待所有的promise对象都达到了resovle再执行then方法进行操作。这样是可以完成的,但是当我们发送1000个请求,等待1000个请求完成后在进行操作,首先不说等待完成操作,就简简单单的http请求瞬间发生1000个,你猜浏览器会怎么样?只能说友谊的小船说翻就翻,因为瞬间发出大量的http请求,导致浏览器堆积了很多栈,导致内存溢出。

并发控制孕育而生,如何实现思路?

身为开发者我们无法控制http请求的多少,但是我们能控制异步任务的数量,具体来说就是我们可以控制promise的实例化数量,用以避免高并发带来的问题。当我们想要的(数量自己输入)promise的数量全部resolve的时候,再将其他的promise放入队列。

直接放代码进行解释:
async function asyncPool(poolLimit = 1,array = [] , interatorFn ){
	const result = [];
	const executing = [];
	for(let item in array){
	 // 生成一个 promise 实例,并在 then 方法中的 onFullfilled 函数里返回实际要执行的 promise,
		const promise = interatorFn(item);
		result.push(promise);
		const e = promise.then(()=>{
		
     // 将执行完毕的 promise 移除
			executing.splice(executing.indexOf(e),1)
        })
        executing.push(e)
        if(poolLimit >= array.length){
			await Promise.race(executing);
         }
	}
 }
 return Promise.all(result);
}


// ----------- 使用 ------- //
    function b() {
        return new Promise((resolve, rejetc) => {
            setTimeout(() => {
                resolve('b')
            }, 100)
        })
    }


    function c(i) {
        return new Promise((resolve, rejetc) => {
            setTimeout(() => {
                resolve('c')
            }, 100)
        })
    }


    function d() {
        return new Promise((resolve, rejetc) => {
            setTimeout(() => {
                resolve('d')
            }, 100)
        })
    }

  let a = asyncPool(2, [b(), c(), d()], (i) => {
        return Promise.resolve(i);
    });

    a.then(res => {
        console.log(res)
    })