如何(优雅地)用Q中断Promises链执行 [英] How to (elegantly) interrupt Promises chain execution with Q

查看:114
本文介绍了如何(优雅地)用Q中断Promises链执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列承诺,如下所示:

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

我的问题是关于行 res.sendStatus( 404)。这是否是打断承诺链执行的正确而优雅的方式?背景是,有时当链接承诺时,我发现了像这样的场景,你需要停止链的执行,原因是不是错误。我知道我可以在 data.length === 0 上抛出一个人为错误,但这对我来说看起来不太优雅。

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.

在上面的代码中,当 data.length === 0 为真时,我只返回一个http响应并且不向promise解析器返回任何值,因此有效地防止链执行继续。但是,我想验证这是否是推荐的做法。留下中途的承诺看起来像是它可能会成为未来的麻烦(内存泄漏?)

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

推荐答案

由于您使用的是现代节点,以下是我使用 Q.async

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?

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

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

(注意,我个人更喜欢使用 bluebird 库出于性能原因,我使用 Promise.coroutine )。

(Note, personally I much prefer using the bluebird library for performance reasons, where I'd use Promise.coroutine).

这篇关于如何(优雅地)用Q中断Promises链执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆