蓝鸟承诺链:与结果“抓”

为了使这个问题对尽可能多的人有用,除了我在下面使用Node + Express的Bluebird承诺库之外,我将排除我的具体实现细节。

所以,假设我有下面的链( P返回一个promise, res是Express 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的错误。 如果我遇到错误,我想loggingpVal1 ,然后发送一个500错误,就像在第一个catch中所做的那样。 但是,我不知道这是如何构build我的链条的可能性。

我相信我需要做一些“分支”,但是我并不认为我理解这个概念足以阻止JavaScript的asynchronous性,从而获得最好的效果! 因此,任何帮助是完全赞赏。

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

捕获链中间的错误是间歇性的error handling; 链条继续运行,所以不要发送回应。

这里有一些东西可以尝试一下:

 // 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> 

如果使用明确的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){ // .... });