2015-07-12 65 views
6

为了让这个问题对尽可能多的人有用,我将排除我的具体实现细节,超出了我在以下使用蓝鸟承诺库和Node + Express的事实。Bluebird Promise Chains:'Catch'与结果

所以,让我们说,我有以下的链(其中P返回一个承诺,res是快速HTTP响应对象):

P().then(function(){ 
    // do nothing if all went well (for now) 
    // we only care if there is an error 
}).catch(function(error){ 
    res.status(500).send("An error occurred"); 
}).then(function(){ 
    return P(); 
}).then(function(pVal1){ 
    return [pVal1, P()]; 
}) // TODO: catch an error from P() here and log pVal1 
.spread(function(pVal1, pVal2){ 
    if(pVal1 === pVal2) { 
     console.log("Success!"); 
    } else { 
     console.log("Failure"); 
    } 
}); 

当我把上面的TODO评论是在那里我会喜欢发现我拨打P时可能发生的错误。如果我遇到了错误,我想登录pVal1,然后发送500错误,就像在第一次捕获中所做的那样。但是,我不确定这是否可能与我如何构建我的连锁店。

我相信我需要做一些“分支”,但我不认为我理解这个概念足够好,以阻止JavaScript的异步性质从我这里得到最好的结果!因此,任何帮助都被完全赞赏。

+0

如果我这样做是完全错误的,请让我知道! – nmagerko

+1

@torazaburo不,它不是。 –

+0

@BenjaminGruenbaum为什么不呢? –

回答

2

不要忘记在链条末尾发现错误。这也是发送回复的地方。

链中间的捕获错误是间歇性错误处理;该链继续运行,所以不要只发送响应。

这是值得尝试一下:

// example middleware 
 
function handle(req, res, next) { 
 
    log("----------------"); 
 
    return async("p1", "foo").then(function (pVal1) { 
 
     return pVal1; 
 
    }).then(function (pVal1) { 
 
     var p2a = async("p2a", "bar"), 
 
      p2b = async("p2a", "bar").catch(function (error) { 
 
       log("Logging: " + error + " (pVal1 " + pVal1 + ")"); 
 
      }); 
 
     return [p2a, p2b]; 
 
    }).spread(function (pVal1, pVal2) { 
 
     if (pVal1 === pVal2) { 
 
      res.send("Success!"); 
 
     } else { 
 
      res.send("Failure"); 
 
     } 
 
    }).catch(function (error) { 
 
     res.status(500).send("An error occurred"); 
 
     log("Logging: " + error); 
 
    }); 
 
} 
 

 
// --------------------------------------------------------------------- 
 
// mockup response object 
 
var res = { 
 
    status: function (code) { 
 
     log("Sending status: " + code); 
 
     return this; 
 
    }, 
 
    send: function() { 
 
     log("Sending response: " + [].join.call(arguments, " ")); 
 
     return this; 
 
    } 
 
}; 
 

 
// mockup promise generator 
 
function async(name, value) { 
 
    return new P(function (resolve, reject) { 
 
     if (confirm("let " + name + " succeed?")) { 
 
      log(name + " succeeds..."); 
 
      resolve(value); 
 
     } else { 
 
      log(name + " fails..."); 
 
      reject(name + " has failed"); 
 
     } 
 
    }); 
 
} 
 

 
function log() { 
 
    var msg = document.createElement("DIV"); 
 
    msg.textContent = [].join.call(arguments, " "); 
 
    document.getElementById("log").appendChild(msg) 
 
    document.body.scrollTop = document.body.scrollHeight; 
 
}
button { 
 
    position: fixed; 
 
    top: 5px; 
 
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script> 
 

 
<button onclick="handle(null, res, null)">Go</button> 
 

 
<div id="log"></div>

+0

啊,'then'里面的'catch'可能是我错过的东西。我甚至没有想过如此构造它。这个例子也使这个很好的答案! – nmagerko

1

如果您使用显式Promise.all不是返回数组.spread的这是可能的。

}).then(function(pVal1){ 
    // this becomes a `Promise.all` - the aggregation is explicit 
    var all = Promise.all([pVal1, P()]); 
    all.catch(function(e){ // "branching", we both return and `catch` the promise 
     console.log("Error, pVal1 is", pVal1); 
    }); 
    return all; // return it 
}).spread(function(pVal1, pVal2){ 
     // .... 
}); 
+0

这种类型的代码不会导致“未处理的拒绝”吗? – Bergi

+0

@Bergi试试:) –

+0

好的,我做了,是的,它记录了一个未处理的拒绝(我的预感是正确的,但我仍然不完全了解“未处理”的条件)。但是,我们想要吗? – Bergi

相关问题