在 JS 中使用 Promises 循环

Looping with Promises in JS

我正在尝试 运行 在 nodejs 的 for 循环内查询,并且 for 循环的每次迭代 运行 都是一个查询。查询是使用 "get()" 方法完成的,该方法 returns 是一个 Promise。在我的函数(包含这个 for 循环)中,我返回 get() 方法返回的承诺,如下所示:

for(var i=0; i < productIds.length; i++) { return queryObject.get(productIds[i]).then(//handle result) }

但是这个 returns 在第一次迭代之后不会继续进行其余的迭代。我该如何解决这个问题?

对于上下文,我正在使用 Parse 的云函数。

你必须像这样建立一个承诺链:

let chain = Promise.resolve();

for (i=0; i<1000; i++) {
   chain = chain.then(()=>queryObject.get(objectId))
}

chain.then(()=>{ /* do something once all queries have returned a result */})

两种可能性,并行和串行。我会展示两者:

async function serial(productIds) {
  for(const productId of productIds) {
      await queryObject.get(productId).then(//handle result)
  }
}

function parallel(productIds) {
  return Promise.all(
     productIds.map( productI => queryObject.get(productId).then(//handle result)
  );
}

TLP给出的答案证明了Promise Chaining,在这里对你有用。但是,我将详细解释正在发生的事情并提供替代答案。

首先,让我们了解一下为什么您的代码无法执行您想要的操作:

for(var i=0; i < productIds.length; i++) {
    return queryObject.get(productIds[i]).then(//handle result)
}

您希望每个 productId 的代码 运行;但是,您在第一次迭代中告诉代码 return,退出 for 循环。思考以下问题:

for(var i=0; i < productIds.length; i++) {
    return productIds[i];
}

从图片中删除承诺可以更容易地看到错误。这个 for 循环等同于:

return productIds[0];

同样,您的代码等同于:

return queryObject.get(productIds[0]).then(//handle result)

假设您看到这里的错误,现在我将指出您的思考过程中的一个小错误,导致您来到这里。在你的 post 你说:

I am returning the promise returned by the get() method like so:

您指的是从 "the" 调用 get() 方法得到的单个承诺 return,但实际上您希望多次调用 get() 方法,从而产生 许多承诺

如果所有这些都有意义,那么您的下一步是决定是否:

  1. 您需要 运行 在完成所有承诺后进行编码(使用检索到的数据的完整列表)。
  2. 您只需要 运行 每个已完成的承诺(仅使用从特定承诺中检索到的数据)的代码。

您使用 Promise Chaining 获得了第一名,如 TLP 的回答所示。您可以通过简单地从代码中删除 "return" 来实现#2,即:

for(var i=0; i < productIds.length; i++) {
    queryObject.get(productIds[i]).then(//handle result)
}