【问题标题】:Does done() accomplish the same thing as catch() in Javascript promises (using sequelize and bluebird)?done() 是否与 Javascript 承诺中的 catch() 完成相同的事情(使用 sequelize 和 bluebird)?
【发布时间】:2017-01-04 03:22:21
【问题描述】:

我正在尝试让我的 Express 应用程序尽可能相似地处理所有请求。我有一台服务器可以处理所有回调,而末日金字塔非常可怕。也很难确保我正在为所有呼叫发送响应。

所以我正在迁移到基于 Promise 的系统(sequelize,它利用了 bluebird 的 promise 库)。

我了解到,最好始终拨打.catch(function(err){ report it } 电话跟进。

.done() 也完成同样的事情吗?

我的想法(可能很天真)是我可以处理.done(success, failure) 函数中的所有res.status(x).send(y) 调用。

failure 会捕捉到 catch() 会捕捉到的一切吗?在done() 函数中发送所有响应是否错误(success 中的所有成功消息和failure 中的所有失败/错误消息?

编辑 - 我发现 sequelize 使用 bluebird 的 promise 库,因此 done() 已被 finally() 贬低。但是,finally() 不接受函数中的参数,所以我似乎无法将所有数据发送到 finally() 并在那里处理。

【问题讨论】:

  • 我在文档中没有看到任何 done 函数,但我确实看到了 then。你在使用 Promise 库吗?
  • 续集。我认为 done() 在 Promise 中是原生的,这可以解释为什么我在它上面找不到太多。
  • 我也不太确定 Sequelize 是否有它。我仍然没有找到任何 done 函数。你确定你没有使用像Q 这样的库吗? done 是 Promises 的非标准函数。不同的库以不同的方式实现它。一些图书馆无视failure
  • 我挖掘了 sequelize 的源代码,发现它是基于 bluebird 的 promise 库构建的。这意味着done() 已被贬低,我应该改用finally()。我认为...(编辑问题以反映这一发现)
  • Bluebird 是 ES6 标准 Promise 的超集。您没有显示您的确切代码,因此我们可以更具体地响应您的情况,但通常,您会使用someAsyncOperation().then(...).catch(...);。这在 ES6 标准 Promise 或 Bluebird Promise 中是正确的。 .then() 处理成功,.catch() 处理错误。您也可以将第二个处理程序传递给.then() 作为错误处理程序,但许多人发现使用.catch() 处理错误更好。 .finally() 不同,Bluebird 文档对此进行了描述。我会避免.done()

标签: javascript node.js express sequelize.js bluebird


【解决方案1】:

Native Promise 没有.done() 方法。我建议坚持使用 ECMAScript spec 并仅使用 .then(success).catch(failure) 这将确保您的 success 函数中可能引发的任何错误仍然被您的 failure 函数捕获和处理。

【讨论】:

  • 我正在使用续集。我认为 done() 是原生的承诺。我误解了。我猜上面的问题是续集而不是承诺。
  • then 允许第二个函数作为处理catch的参数
  • 我做了一些挖掘,发现 sequelize 是建立在 bluebird 的 promise 库上的。所以这是finally()catch() 的问题。 (编辑问题以反映这一点)
  • @4castle 是的,但这样做的问题是传递给.then() 的第一个参数中可能发生的任何错误都不会被第二个处理。这就是为什么在 .then() 之后添加一个额外的 .catch() 几乎总是一个更好的主意,以捕获所有可能的错误。
  • 那很好:) 请注意,本机承诺没有done 的原因是因为不需要它。 done 出现在我们可以自动跟踪未处理的拒绝并需要明确终止承诺链之前 - 它容易出错,我强烈建议不要这样做。
【解决方案2】:

.finally(function() handler) -> Promise 函数略有不同。它会为successfailure 调用,但请注意它没有获取任何数据作为handler 的参数。

它旨在用于清理,就像try...catch 中的普通finally 块一样。

如果您需要访问 Promise 返回的值,请使用.then()

.then(
    [function(any value) fulfilledHandler],
    [function(any error) rejectedHandler]
) -> Promise

【讨论】:

  • 使用then(success).catch(error)不是更好吗?
  • .catch(handler) 只是.then(null, handler) 的简写函数。如果使用catch 更具可读性,那很好。
  • @Matt 会是,正如我在回答中所解释的那样。
【解决方案3】:

done() 已弃用,我建议您不要使用它 - 它的目标是将拒绝作为异常抛出,以便传播。 Bluebird 会自行跟踪未解决的承诺,因此 then 会这样做并发出警告。

你确实想做.catch(err => { /* handle */}),除非你真的有能力处理异常——就像catch (e) {一样。如果您对异常没有任何意义,请不要做任何事情。

例如,在路由中,如果发生异常,您可以返回 500 错误状态,并向您的工具和客户端报告某些内容。

finally() 主要用于资源清理 并确保您将所有内容保持在干净状态。

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 2016-03-01
    • 2014-11-24
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    相关资源
    最近更新 更多