2015-10-04 94 views
3

我有诺言链,看起来像这样:如何(优雅)中断承诺链执行符合Q

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);  
    }); 
} 

我在这里的问题是关于线res.sendStatus(404)。这是一种中断承诺链执行的正确和优雅的方式吗?背景是,有时当链接承诺时,我发现类似这样的情况,您需要停止执行链的原因是不是错误。我知道我可以在data.length === 0上抛出一个人为错误,但这对我来说看起来很不雅观。

在上面的代码中,当data.length === 0为真时,我只是返回一个http响应,并且不会将任何值返回给promise解析器,从而有效地阻止链执行继续。不过,我想验证这是否是推荐的做法。留下一个承诺挂中途在我看来就像它可以是一个麻烦,今后源(?内存泄漏)

+0

您是否使用本地承诺? – thefourtheye

+0

@thefourtheye我正在使用Q库(kriskowal) –

+0

@LuisDelgado您运行的是哪个版本的Node? –

回答

2

由于您使用现代化节点,这里是我将如何使用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; 
}); 

读取像一个同步功能,完全平坦,好吧?

我省略了从req/res中提取内容的代码,因为这会使代码更难以测试,而且它应该可以分开。我这样称呼它:

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); 
    }); 
} 

(注意,我个人更喜欢使用bluebird库性能方面的原因,在这里我会使用Promise.coroutine)。