如下函數已 10 個併發請求爲標準,超過 10 個的部分按調用順序進行排隊,當前一個請求完成時,再發送隊列中的下一個請求。數組
function concurrentPoll(){ this.tasks = []; // 任務隊列 this.max = 10; // 最大併發數 setTimeout(() => { // 函數主體執行完後當即執行 this.run() },0) } concurrentPoll.prototype.addTask = function(task){ // 原型添加任務方法 this.tasks.push(task) } concurrentPoll.prototype.run = function(){ // 原型任務運行方法 if(this.tasks.length == 0){ // 判斷是否還有任務 return } var min = Math.min(this.tasks.length, this.max); // 取任務個數與最大併發數最小值 for(var i = 0; i < min; i++){ this.max--; // 執行最大併發遞減 var task = this.tasks.shift(); // 從數組頭部取任務 task().then((res) => { // 重:此時可理解爲,當for循環執行完畢後異步請求執行回調,此時max變爲0 console.log(res) }).catch((err) => { console.log(err) }).finally(() => { // 重:當全部請求完成並返回結果後,執行finally回調,此回調將按照for循環依次執行,此時max爲0. this.max++; // 超過最大併發10之後的任務將按照任務順序依次執行。此處可理解爲遞歸操做。 this.run(); }) }} var poll = new concurrentPoll(); // 實例 for (var i=0; i<13; i++) { // 數據模擬 poll.addTask(function () { return new Promise( function (resolve, reject) { // 一段耗時的異步操做 resolve('成功') // 數據處理完成 // reject('失敗') // 數據處理出錯 } )}) }