如何创建承诺循环



所以我有一个承诺,从服务器收集数据,但一次只收集50个响应。 我有 250 个回复要收集。

我可以像下面这样一起兑现承诺

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 个结果,所以这似乎是一个可管理的解决方案,但有没有办法在循环中连接承诺。 所以我运行一个循环 5 次,每次运行下一个承诺。

对不起,我是承诺的新手,如果这是回调,这就是我会做的。

如果你想循环和序列化承诺,一旦一个失败就不执行任何其他get调用,那么试试这个循环:

async function getAllResults() {  // returns a promise for 250 results
    let totalResults = [];
    try {
        for (let i = 0; i < 5; i++) {
            totalResults.push(...await getResults.get());
        }
    } catch(e) {};
    return totalResults;
}

这使用 EcmaScript2017 asyncawait语法。如果不可用,请将承诺与then链接:

function getAllResults() {
    let totalResults = [];
    let prom = Promise.resolve([]);
    for (let i = 0; i < 5; i++) {
        prom = prom.then(results => {
            totalResults = totalResults.concat(results);
            return getResults.get();
        });
    }
    return prom.then(results => totalResults.concat(results));
}

请注意,应避免使用承诺构造反模式。这里没有必要使用new Promise

还可以考虑在上述函数返回的 promise 上添加一个.catch()调用,以处理错误条件。

最后,请注意,concat不会修改调用它的数组。它返回串联数组,因此您需要分配该返回值。在代码中,不分配返回值,因此调用不起作用。

另请参阅 JavaScript ES6 promise for loop。

可能你只需要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
}

最新更新