2017-03-19 108 views
6

所以我有一個承諾,從服務器收集數據,但一次只收集50個響應。我有250個回覆收集。如何創建一個承諾循環

我可能只是concate承諾在一起,就像下面

new Promise((resolve, reject) => { 
    resolve(getResults.get()) 
    }) 
    .then((results) => { 
    totalResults.concat(results) 
    return getResults.get() 
    }) 
    .then((results) => { 
    totalResults.concat(results) 
    return getResults.get() 
    }).then((results) => { 
    totalResults.concat(results) 
    return getResults.get() 
    }) 

在這種情況下,我只需要250個結果,因此這似乎是一個易於管理的解決方案,但有一個循環concating承諾的一種方式。所以我運行循環5次,每次運行下一個承諾。

對不起,我對承諾是新的,如果這是回調,這是我會做的。

+1

'get'是否會返回一個承諾? –

+0

我建議查看[async](http://caolan.github.io/async/)庫。它會讓你的生活更輕鬆。看看'async.eachLimit'功能。 – forrestmid

+0

@forrestmid不,這不符合承諾。 – Bergi

回答

7

如果要循環和序列化的承諾,不執行任何其他get調用一次一個失敗了,那就試試這個循環:

function getAllResults() { // returns a promise for 250 results 
    let totalResults = []; 
    let prom = getResults.get(); 
    for (let i = 0; i < 4; i++) { // chain four more times 
     prom = prom.then(results => { 
      totalResults = totalResults.concat(results); 
      return getResults.get(); 
     }); 
    } 
    return prom.then(results => totalResults.concat(results)); 
} 

請注意,你應該避免promise construction anti-pattern。這裏沒有必要使用new Promise

還可以考慮在上述函數返回的promise上調用.catch()來處理錯誤條件。

最後,請注意,concat不會修改您調用它的數組。它返回連接的數組,所以你需要分配返回值。在你的代碼中你不分配返回值,所以這個調用沒有效果。

+2

你可能想從'prom = Promise.resolve([])'開始,這樣你就不必重複get調用並且連接,並且適當地計數到5。 – Bergi

+0

謝謝你這很好。優秀的建議 –

8

也許你只需要Promise.all方法。 對於每一個請求你應該創建一個承諾,並把它放在一個數組中,然後你用all方法包裝一切,你就完成了。

示例(假設getResults.get回報承諾):

let promiseChain = []; 
for(let i = 0; i <5; i++){ 
    promiseChain.push(getResults.get()); 
} 

Promise.all(promiseChain) 
    .then(callback) 

你可以閱讀更多關於這種方法在這裏: Promise.all at MDN

編輯 您可以訪問由這樣的承諾返回的數據:

function callback(data){ 
    doSomething(data[0]) //data from the first promise in the chain 
    ... 
    doEventuallySomethingElse(data[4]) //data from the last promise 
} 
+0

你會如何建議OP使用這種方法從get()調用中獲得結果? – rasmeister

+0

請看編輯;) – Phugo

+0

謝謝,但這是返回相同的50個結果5次 –