How to (elegantly) interrupt Promises chain execution with Q

馋奶兔 提交于 2019-12-23 16:06:27

问题


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). 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.

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. 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?)


回答1:


Since you are using modern node, here is how I would write it using 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. 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).



来源:https://stackoverflow.com/questions/32935312/how-to-elegantly-interrupt-promises-chain-execution-with-q

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!