在 Express.js 中停止执行 Sequelize 承诺
Posted
技术标签:
【中文标题】在 Express.js 中停止执行 Sequelize 承诺【英文标题】:Stop execution of a Sequelize promise in Express.js 【发布时间】:2014-07-28 07:17:59 【问题描述】:我刚接触 promise 的世界,我不确定我是否完全理解在某些情况下如何使用它们。
Sequelize 最近添加了对 Promise 的支持,这确实使我的代码更具可读性。一个典型的场景是避免在无限回调中多次处理错误。
下面的 sn-p 总是返回204
,而我希望它在找不到照片时返回404
。
有没有办法告诉 Sequelize 在发送 404 后“停止”承诺链的执行?请注意,res.send
是异步的,因此它不会停止执行。
// Find the original photo
Photo.find(req.params.id).then(function (photo)
if (photo)
// Delete the photo in the db
return photo.destroy();
else
res.send(404);
// HOW TO STOP PROMISE CHAIN HERE?
).then(function ()
res.send(204);
).catch(function (error)
res.send(500, error);
);
当然,这个例子很简单,可以很容易地用回调来编写。但在大多数情况下,代码会变得更长。
【问题讨论】:
您需要一种方法来将承诺标记为此时已解决。我不熟悉 sequelize,但我认为一定有办法做到这一点。 谢谢埃德温。我唯一知道的是 Sequelize 使用的是 Bluebird。但是,我在他们的 API 中看不到任何可以让我停止承诺链的内容。 如果您在throw
处理程序中使用 throw
,则会拒绝该链。还有一个(未解决的问题)[github.com/sequelize/sequelize/issues/272],如果未找到结果,则自动拒绝 find 调用。如果您需要该功能,您可以在那里表达您的支持
听起来不错!我今天将添加评论。现在,投掷似乎也是一个很好的后备。谢谢你的回答:)
好的,我发布了一个相关的拉取请求并得到了我的最终答案。看起来最好的解决方案是按照您的建议在then
内使用throw
。 github.com/sequelize/sequelize/pull/934
【参考方案1】:
您的承诺链不一定是线性的。您可以“分支”并为成功案例创建一个单独的承诺链,根据需要链接尽可能多的.then()
,同时为失败案例创建一个单独的(较短的)承诺链。
从概念上讲,它看起来像这样:
Photo.find
/ \
/ \
(success) (failure)
/ \
/ \
photo.destroy res.send(404)
|
|
res.send(204)
在实际的代码中,它看起来像这样:
// Find the original photo
Photo.find(req.params.id).then(function (photo)
if (photo)
// Delete the photo in the db
return photo.destroy().then(function ()
res.send(204);
);
else
res.send(404);
).catch(function (error)
res.send(500, error);
);
【讨论】:
是的,这就是我最终所做的。我期待 Sequelize 简单地拒绝我的find()
承诺,以避免嵌套代码过多。最后一个问题:你知道我是否也需要为destroy()
承诺添加catch()
吗?还是最后会被catch处理?谢谢!
@PedroCheckos,除非您在 Photo.destroy()
承诺链中定义单独的 catch()
块,否则任何未处理的异常都应“冒泡”到外部 catch()
块。
太棒了,这就是我需要知道的全部内容!非常感谢您的提示:)
@PedroCheckos,我只是偶然发现了这个并记住了这个问题:Promise Cancellation in bluebird。 (请注意,bluebird 似乎是 sequelize.js 在幕后使用的。)我不知道“可取消的承诺”是一回事。进一步的研究也引出了这个问题,其中有一些很好的信息:Status of cancellable promises。也许这会给你一些尝试的想法。以上是关于在 Express.js 中停止执行 Sequelize 承诺的主要内容,如果未能解决你的问题,请参考以下文章
在 Express.js 中为啥 res.json() 之后的代码仍然执行?
如何在 Express.js 服务器上执行 JWT API 请求? (edX API)