【问题标题】:How can I avoid breaking a promise chain when using q.map?使用 q.map 时如何避免破坏承诺链?
【发布时间】:2015-04-02 14:39:04
【问题描述】:

我想我可能对承诺过于看中了。我有一组鹅,在返回最终值之前,我想执行任意数量的操作。我发现在第一个 return 语句之后,链条就断了。如果我的集合有 10 个项目,则恰好有 10 个项目将放置在数据库中,但是当我尝试从下面的“return Q.all(promises)”语句构建我的 API 响应时,我得到空值。

为了测试,我在第一个之后触发的 promise 中放入了一个 console.log 语句,并在我的 expressjs 路由中放入了一个 console.log ,它期待有关 geese 的详细信息。 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);

【问题讨论】:

  • 有点题外话,但您的第一个回调可以缩短为.then(recordNewGooseType)

标签: node.js promise q


【解决方案1】:

你没有一个 promise 数组,你有一个 undefined 值数组(Q.all 没有警告你):你的 mapper 函数没有返回任何东西。您在那里缺少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);

【讨论】:

  • 他说他永远不会在链内达到第二个 - 虽然返回确实丢失了这不可能是(唯一的)问题。
  • @BenjaminGruenbaum:我不确定,但我解释了“API 响应总是完成首先“[null, null]”然后最终我在链中获得了我的第二个和第三个承诺的条目”,因为“从不”是不准确的,他的日志语句只有“错误”的时间安排。如果修复return后还有其他问题,他确实应该看看你的答案。
【解决方案2】:

这意味着有两种选择:

recordNewGooseType 被错误地承诺或determineGooseType 被错误地承诺。具体来说 - 既然你说 API 响应 determineGooseType 返回 [null, null] 唯一合理的假设是 recordNewGooseType 是罪魁祸首。

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

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

【讨论】:

    猜你喜欢
    • 2016-11-07
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 2016-04-17
    • 2016-12-24
    • 1970-01-01
    相关资源
    最近更新 更多