使用 q.map 时如何避免破坏承诺链?

How can I avoid breaking a promise chain when using q.map?

我想我可能太看重诺言了。我有一个鹅数组,在 return 最终值之前我想执行任意数量的操作。我发现在第一个 return 语句之后,链条断开了。如果我的集合有 10 个项目,那么恰好 10 个项目将被放入数据库中,但是当我尝试从下面的 "return Q.all(promises)" 语句构建我的 API 响应时,我得到了空值。

为了测试,我在一个承诺中放置了一个 console.log 语句,该语句在第一个语句之后触发,并在我的 expressjs 路由中放置了一个 console.log ,它期待关于鹅的详细信息。 API 响应总是首先完成“[null, null]”,然后最终我在链中获得了我的第二个和第三个承诺的条目。

我是如何产生这种竞争条件的,我该如何解决它?

var promises = geese.map(function(goose) {
 determineGooseType(goose.details)
  .then(function(type) {
    return recordNewGooseType(type)
  })
  .then(function(dbInsertResult) {
    we never really got here!
  })
  .catch(function(err) {
   log some stuff
  });
}

return Q.all(promises);

这意味着有两个选项:

要么 recordNewGooseType 被错误地承诺了,要么 determineGooseType 被错误地承诺了。具体来说 - 因为你说 API 响应 determineGooseType returns [null, null] 唯一合理的假设是 recordNewGooseType 是罪魁祸首。

这意味着承诺的 recordNewGooseType 没有调用 resolve

你可以通过 运行 一只鹅而不是 10 只鹅来验证这一点。

你没有一组承诺,你有一组 undefined 值(并且 Q.all 没有警告你):你的映射器函数没有返回任何东西。您在那里缺少 return 语句:

var promises = geese.map(function(goose) {
  return determineGooseType(goose.details)
//^^^^^^
  .then(function(type) {
    return recordNewGooseType(type)
  })
  .then(function(dbInsertResult) {
    // now getting here before resolving the .all() promise!
  })
  .catch(function(err) {
   log some stuff
  });
}
return Q.all(promises);