为了使这个问题对尽可能多的人有用,我将排除我的具体实现细节,除了我在下面使用带有Node + Express的Bluebird promise库。
所以,让我们说我有以下链(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
来电时可能出现的错误。如果我发现错误,我想记录pVal1
然后发送500错误,就像第一次捕获一样。但是,我不确定这是否可能与我如何构建我的链。
我相信我需要做一些"分支,"但我认为我不能理解这个概念,以阻止JavaScript的异步性质让我最好!因此,任何帮助都是非常感激的。
答案 0 :(得分: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>
&#13;
答案 1 :(得分: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){
// ....
});