2016-11-22 71 views
0

我使用promises處理任務的列表:Javascript - 如何正確處理循環承諾?

這是一個代碼示例:

var array = ["aaa", "bbbb", "cccc", "dddd", "eeee"]; 
var result = []; 
var p = Promise.resolve({ 
    then: function(onFulfill, onReject) { 
    array.forEach(function(x){ 
    // http request with x and make sure this request ends before a new one if fired 
    // put http resolte in array : result.push(httpRespose); 
    }); 
    //when done, onFulfill(result) 
} 
}); 
p.then(
function(v) { 
    console.log(v); // "fulfilled!" 
    }, function(e) { 
     console.log(e); // not called 
}); 

我希望能夠製作和使用來自陣列的每個元素的HTTP請求,然後把結果另一個數組,當完成時返回新的數組。我也想知道是否有可能確保http結果以相同的順序添加(這不是很重要)。

有人可以幫忙嗎?

+0

創建承諾的數組,並用'Promise.all'解決這些問題:https://developer.mozilla.org/en-US/docs/Web/JavaScript/參考/ Global_Objects/Promise/all。 –

+0

你可以將所有的promise集合到一個數組中,並使用[Promise.all](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)來觸發他們都已完成。 –

+0

'//使用x的http請求並且確保這個請求在一個新的請求結束之前結束如果是這樣的話,你不需要promise.all –

回答

1

Promise.all用於等待許多承諾履行。

每次創建一個承諾,將其推到一個數組,然後用

Promise.all(myPromiseArray).then(allDoneHandler)

下面是一個例子:

var items = [ 500, 1000, 1500 ]; 
 
var results = []; 
 
items.forEach((item) => { 
 
    let promise = new Promise((resolve) => { 
 
    setTimeout(() => { 
 
     console.log(item); 
 
     resolve(item); 
 
    }, item); 
 
    }); 
 
    results.push(promise); 
 
}); 
 
Promise.all(results).then(() => { 
 
    console.log('done!'); 
 
}); 
 
     

+0

Nit:'var results = items.map(item => new Promise(...));' –

+0

@FelixKling謝謝。這將在我的例子中起作用,但爲了簡單起見,我不想壓縮太多*。 – xdumaine

+0

One-liner:Promise.all(items.map(makeAjaxRequest)))。然後(console.log) – tjoskar

1

「跑承諾」按順序(特別是從陣列),您可以使用此模式:

var donePromise = arrayOfData.reduce(function(sequence, value, index){ 
    return sequence.then(function(){ 
     //doSomethingWithValueAndReturnAPromise 
    }) 
}, Promise.resolve()); 

但因爲你想要的結果積累的,不僅是一個指示燈,當工作完成了,我們需要modufy此:

我們使用Array.map()Promise.all()積累的結果,類似的如上述方法,以確保順序執行:

var urls = [/*...*/]; 

var _sequence = Promise.resolve(); 
Promise.all(urls.map(function(url) { 
    return _sequence = _sequence.then(function(){ 
     //fetch the url and return a Promise: 
     //return fetch(url).then(response => response.text()) 
    }); 
})).then(function(results){ 
    //console.log(results) 
});