在 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 承诺的主要内容,如果未能解决你的问题,请参考以下文章

工具Sequel Pro简介

在 Express.js 中为啥 res.json() 之后的代码仍然执行?

sequel pro 中的循环和迭代入门

如何在 Express.js 服务器上执行 JWT API 请求? (edX API)

在 Mongoose 模型中访问 Express.js 请求上下文

我不能用express.js执行jade(pug)