【问题标题】:Stop execution of a Sequelize promise in Express.js在 Express.js 中停止执行 Sequelize 承诺
【发布时间】: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 内使用throwgithub.com/sequelize/sequelize/pull/934

标签: javascript node.js express sequelize.js


【解决方案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。也许这会给你一些尝试的想法。
猜你喜欢
  • 2013-05-04
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2018-03-18
  • 2016-03-07
  • 2018-08-20
  • 2014-12-29
  • 1970-01-01
相关资源
最近更新 更多