Promise 實現併發請求限制
阿新 • • 發佈:2020-09-10
Promise 併發限制
-
併發請求限制,n個請求,每次最多隻能同時存在limit個請求,剩餘的在佇列中等待。
-
promiseAll 實現併發請求,n個請求,每次最多同時請求limit個,所有請求完成後處理資料。
併發請求限制
思路: 定義一個請求池,run 函式每次將等待佇列中任務加入到請求池中,直到塞滿或等待佇列空。再每個task執行完成後通過finally繼續執行run函式,addTask 為往等待佇列中新增任務,並執行run。
var startTime =new Date().getTime() function taskPool(){ this.tasks = []; this.pool = []; this.max = 2; } taskPool.prototype.addTask = function(task){ this.tasks.push(task); this.run(); } taskPool.prototype.run = function(){ if(this.tasks.length ===0) return; let min = Math.min(this.tasks.length, this.max - this.pool.length); for(var i=0;i<min;i++){ var currTask = this.tasks.shift(); this.pool.push(currTask); currTask().then(res=>{ console.log(new Date().getTime() - startTime); }).catch(err=>{ }).finally(()=>{ this.pool.splice(this.pool.indexOf(currTask), 1); this.run(); }) } } var pool = new taskPool(); for(let i=0;i<5;i++){ pool.addTask(function(){ return new Promise(resolve=>{ setTimeout(()=>{ resolve(i); },500); }).then(res=>{ console.log('resolved' ,res); }) }) } /** 輸出: resolved 0 500 resolved 1 500 resolved 2 1000 resolved 3 1000 resolved 4 1500 **/
promiseAll 併發請求限制
var startTime =new Date().getTime() function asyncPool(array, limit){ let index = 0; let res = []; let pool = []; let run = function() { if(index === array.length){ return Promise.resolve(); } let item = array[index++]; let promise = Promise.resolve(item()); res.push(promise); let e = promise.then(()=>{ pool.splice(pool.indexOf(e), 1); }) pool.push(e); console.log(`pool size : ${pool.length}`, pool); let r = Promise.resolve(); if(pool.length >= limit){ r = Promise.race(pool); } return r.then(()=>run()); } return run().then(()=>{ console.log(res); return Promise.all(res); }); } var timeout = i => { return function () { return new Promise(resolve=>{ setTimeout(()=>{resolve(i)}, i); }) } } asyncPool([timeout(600),timeout(300),timeout(700),timeout(400),timeout(500)], 2, timeout).then(res=>{ console.log(res); console.log(new Date().getTime() - startTime); }) /** 輸出 [600, 300, 700, 400, 500] 1500 請求1 2 先發起; 1 2 起始時間 0 2請求完成 繼續請求3; 3 起始時間 300 1請求完成 繼續請求4; 4 起始時間 600 3請求完成 繼續請求5; 5 起始時間 1000 5請求完成,所有請求完成,此時時間 1500 **/