Promise 實現並發請求限制


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 
**/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM