2017-03-19 139 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次 –