建站需要哪些東西武漢網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣
asyncPool應(yīng)用場(chǎng)景
一個(gè)不太常見(jiàn)的極端場(chǎng)景,當(dāng)我們?yōu)榱四硞€(gè)操作需要發(fā)生異步請(qǐng)求的時(shí)候,等待所有異步請(qǐng)求都完成時(shí)進(jìn)行某些操作。這個(gè)時(shí)候我們不在簡(jiǎn)簡(jiǎn)單單的發(fā)送 1 - 2 個(gè)請(qǐng)求而是 5 - 10個(gè)(其實(shí)極端場(chǎng)景式 很多很多個(gè)請(qǐng)求,這個(gè)打個(gè)比喻更容易理解)。
通常情況下我們通過(guò) promise.all 可以保證多個(gè)請(qǐng)求完成后進(jìn)行操作,等待所有的promise
對(duì)象都達(dá)到了resovle再執(zhí)行then方法進(jìn)行操作。這樣是可以完成的,但是當(dāng)我們發(fā)送1000個(gè)請(qǐng)求,等待1000個(gè)請(qǐng)求完成后在進(jìn)行操作,首先不說(shuō)等待完成操作,就簡(jiǎn)簡(jiǎn)單單的http請(qǐng)求瞬間發(fā)生1000個(gè),你猜瀏覽器會(huì)怎么樣?只能說(shuō)友誼的小船說(shuō)翻就翻,因?yàn)樗查g發(fā)出大量的http
請(qǐng)求,導(dǎo)致瀏覽器堆積了很多棧,導(dǎo)致內(nèi)存溢出。
并發(fā)控制孕育而生,如何實(shí)現(xiàn)思路?
身為開(kāi)發(fā)者我們無(wú)法控制http請(qǐng)求的多少,但是我們能控制異步任務(wù)的數(shù)量,具體來(lái)說(shuō)就是我們可以控制promise的實(shí)例化數(shù)量,用以避免高并發(fā)帶來(lái)的問(wèn)題。當(dāng)我們想要的(數(shù)量自己輸入)promise的數(shù)量全部resolve的時(shí)候,再將其他的promise放入隊(duì)列。
直接放代碼進(jìn)行解釋:
async function asyncPool(poolLimit = 1,array = [] , interatorFn ){const result = [];const executing = [];for(let item in array){// 生成一個(gè) promise 實(shí)例,并在 then 方法中的 onFullfilled 函數(shù)里返回實(shí)際要執(zhí)行的 promise,const promise = interatorFn(item);result.push(promise);const e = promise.then(()=>{// 將執(zhí)行完畢的 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)})