简体   繁体   English

如何(优雅地)用Q中断Promises链执行

[英]How to (elegantly) interrupt Promises chain execution with Q

I have a chain of promises that looks like this: 我有一系列承诺,看起来像这样:

module.exports.deleteCommunityFollower = function deleteCommunityFollower(req, res){
  var communityId = req.params.userId;
  var followerId = req.session.passport.user.userId;

  var community = new user_model.User(communityId);
  community.getFollower(followerId)
    .then(function(data) {
      if(data.length === 0) {
        res.sendStatus(404); //no follower found, interrupt execution
      } else {
       return community.removeFollower(data[0]); //returns a promise
      }      
    })
    .then(function() {
      res.sendStatus(201); //follower removed, success
    })
    .fail(function(error) {
      errorHelper.diagnosticsUploader(error, community);
      res.sendStatus(500);      
    });
}

My question here is about line res.sendStatus(404) . 我的问题是关于行res.sendStatus(404) Is this a correct and elegant way of interrupting execution of a chain of promises? 这是否是打断承诺链执行的正确而优雅的方式? The background is, sometimes when chaining promises, I've found scenarios like this one, where you need to stop the execution of the chain for reasons that are not an error . 背景是,有时当链接承诺时,我发现像这样的场景,你需要停止链的执行,原因不是错误 I know I could throw an artificial error upon data.length === 0 , but that just looks inelegant to me. 我知道我可以在data.length === 0抛出一个人为错误,但这对我来说看起来不那么优雅。

In the code above, when data.length === 0 is true, I simply return an http response and do not return any value to the promise resolver, thus effectively preventing the chain execution to continue. 在上面的代码中,当data.length === 0为真时,我只返回一个http响应,并且不向promise解析器返回任何值,从而有效地防止链执行继续。 However, I'd like to validate if this is recommended practice. 但是,我想验证这是否是推荐的做法。 Leaving a promise hanging mid-way looks to me like it can be a source of trouble in the future (memory leaks?) 留下一个挂在中途的承诺看起来像是它可能成为未来的麻烦(内存泄漏?)

Since you are using modern node, here is how I would write it using Q.async : 由于您使用的是现代节点,因此我将使用Q.async编写它:

const deleteFollower = Q.async(function*(communityId, followerId){ 
    const community = new user_model.User(communityId);
    let followers = yield community.getFollower(followerId);
    if(followers.length) === 0; return false;
    yield community.removeFollower(follower[0]);
    return true;
});

Reads like a synchronous function and completely flat, nice huh? 读取像一个同步功能,完全平坦,好吧?

I omitted the code extracting things from req/res since that would make the code harder to test and it should probably be separated anyway. 我省略了从req / res中提取内容的代码,因为这会使代码更难以测试,并且它应该可能是分开的。 I'd call it like: 我称之为:

function handler(req, res){
    var communityId = req.params.userId;
    var followerId = req.session.passport.user.userId;
    deleteFollower(communityId, followerId).then(val => {
        if(val) res.sendStatus(201);
        else res.sendStatus(404);
    }).fail(err => {
        res.sendStatus(500);
        errorHelper.diagnosticsUploader(err); 
    });
}

(Note, personally I much prefer using the bluebird library for performance reasons, where I'd use Promise.coroutine ). (注意,我个人更喜欢使用bluebird库,因为性能原因,我使用Promise.coroutine )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM