在我返回res.end()后,Promise仍然会转到下一个链

时间:2016-12-15 02:25:26

标签: javascript node.js express promise bluebird

我在使用express的节点中使用bluebird,当我返回res.end()时,Promise仍然转到下一个链,这是我的代码:

Promise.resolve(operate).then(function(data){
    if (!!data && data.length !=0) {
        log.info('success');
        return true;
    }else {
        log.warn('fail');
        return res.end();
    }
}).then(function(data){
    if(data) {
        log.info('done');
        return res.end();
    }else {
        log.warn('fail');
        return res.end();
    }
})

如果失败了,我在日志中得到2'失败',如果我第一次“失败”,我怎么能让它停止?谢谢!

bluebird版本:~2.10.2; 节点:4.3.1; 表达:〜4.2.0

2 个答案:

答案 0 :(得分:2)

您可以返回错误或拒绝的承诺,而不是res.end。这将跳过所有成功处理程序,直到promise链的末尾(技术上直到第一个拒绝处理程序):

Promise.resolve()
  .then(() => Promise.reject())
  .then(
     () => console.log('this does not run'), // <-- success handler
     () => console.log('this runs')          // <-- rejection handler
  );

所以在你的代码中:

Promise.resolve(operate).then(function(data){
  if (!!data && data.length !=0) {
    log.info('success');
    return true;
  } else {
    log.warn('fail');
    res.end();
    return Promise.reject(/* optionally pass an error */); // <--- return rejected promise
  }
}).then(function(data){
  // this won't run if previous promise rejects
})

答案 1 :(得分:0)

根据定义,then方法总是返回一个Promise,因此链将继续。

正如已经指出的那样,你可以拒绝承诺,然后再抓住它。如果错误处理在所有情况下都相同,那么您可以在链的末尾使用catch(无论如何,将结尾放在最后都被认为是一种好习惯。)

Promise.resolve(operate).then(function(data){
    if (!!data && data.length !=0) {
        log.info('success');
        return true;
    } else {
        return Promise.reject('fail');
    }
})
.then(function(data) {
    // true is being returned above so it will enter here always
    // I guessed something instead of true could come here
    if(data) {
        log.info('done');
        return res.end();
    } else {
        return Promise.reject('fail'); 
    }
})
.catch(function(err) {
    log.warn(err);
    return res.end();
});

在这种情况下,撤销被拒绝的Promise似乎是合法的,但是根据情况返回被拒绝的承诺以逃避Promise链不能被推荐,因为它可能与真正的拒绝混合在一起。在这种情况下,重组您的连锁店可能是最好的选择。