2016-11-22 77 views
0

我一直在尋找,並找到了一些變化,但沒有找到任何符合我的需求。下面是我想弄清楚的僞代碼:我不明白,你不能阻止同步碼等待異步和我嘗試了好幾種變化等待x個承諾完成以產生新承諾的良好模式是什麼?

var itemsUploading = 0; 
const maxUploads = 10; 


function uploadAll(items){ 
    var promises = []; 
    items.forEach(function(item){ 

     /* Here is where I want to wait for itemsCurrentlyUploading < maxUploads */ 

     itemsUploading++;    
     promises.push(upload(item));    
    } 
    return Promise.all(promises); 

} 

function upload(item){ 
    return new Promise(function(resolve, reject){ 

     /*Item upload logic here */ 

    }) 
    .then(function(response){ 
     itemsUploading--; 
    }); 
} 

。我認爲setTimeout是我可以用來做到這一點的東西,但我不太明白必要的邏輯。任何和所有的幫助將不勝感激,如果還有其他事情可以編輯,以幫助某人更好地理解問題,請讓我知道,謝謝!

+0

你需要閱讀關於鏈接Promise和Deferred調用,這裏的關鍵字是'.then()' – rorschach

+2

看看[this](http://stackoverflow.com/a/39197252/1048572)或[this ](http://stackoverflow.com/a/38778887/1048572) – Bergi

回答

1

我想你可能會發現像Bluebird庫中的Promise.map有用。 concurrency參數允許您設置「等待」承諾的最大數量。

簡單的解決方案,但我想不像藍鳥那樣經過戰鬥測試,可以用作standalone NPM package

+0

這是完美的,正是我所期待的。 – goodOldFashioned

0

由於JavaScript在數據結構上有點稀疏,所以我們必須做。

let pending = new Set; 
let maxPendingItems = 5; // could be whatever number 

let wrapPromiseFn = f => (...args) => { 
    let p = f(...args); 
    pending.add(p); 
    p 
    .then(() => pending.remove(p)) 
    .catch(e => { 
     console.warn(e); 
     pending.remove(p); 
    }); 

    return p; 
}; 

let performAsyncIO = wrapPromiseFn(someAJAXFn); 

現在你可以有一個循環,監視集的大小,看它是否已經清理出足夠的添加新的項目。只要確保你像上面那樣用wrapPromiseFn來裝飾你的承諾返回函數。

let flag = true; 
while (flag) { 
    if (pending.size <= maxPendingItems) { 
    // promise will automatically queue until resolved 
    performAsyncIO().then(responseHandler); 
    } 
}