我想这样做:
return1stPromise()
.then(if1stPromiseSucceeds) // returns 2nd Promise
.catch(if1stPromiseFails)
.then(if2ndPromiseSucceeds) // execute only if 1st Promise succeeds
我希望只有在第一个承诺成功时才执行第二个.then
。或者换句话说,如果执行了catch,我不希望第二个.then
执行。
这是可能的吗?或者我是否在第一个then
中嵌套第二个承诺:
return1stPromise()
.then(function (data) {
return if1stPromiseSucceeds(data).then(if2ndPromiseSucceeds);
})
.catch(if1stPromiseFails);
此外-任何好的资源如何控制流与承诺,它更像线程?
你所描述的是典型的情况,当我们想对一个异常做出反应,但实际上不处理它,让代码继续运行:
return1stPromise()
.then(if1stPromiseSucceeds) // returns 2nd Promise
.catch(() => { if1stPromiseFails(); throw e; })
.then(if2ndPromiseSucceeds) // execute only if 1st Promise succeeds
您需要重新抛出异常,以便将其标记为"仍未处理"。
这就像同步代码:
try {
var res = firstResult();
var res2 = ifFirstPromiseSucceeds(res);
} catch (e) {
ifFirstPromiseFails();
throw e; // we reacted to the exception but did not handle it yet.
}
var res3 = ifSecondPromiseSucceeds();
我认为从线程的角度来考虑承诺是很容易混淆的——如果可能的话,找到一个同步的类比总是更容易。
这并不总是可能的,例如,另一种停止承诺链的方式是取消,这有点像带有"我不关心结果"语义的线程中止-你可以在这里阅读它,但我认为对于你的用例来说,它有点过头了,而且不那么好。
我可能会做抛出和捕获,但如果你不想这样做,你总是可以返回一个被拒绝的承诺来绕过下一个then阶段。例如,
new Promise((resolve,reject) => { var rnd = Math.random();
rnd > 0.5 ? resolve(21)
: reject("promise error");
})
.then(val => { var rnd = Math.random();
if (rnd < 0.5) return Promise.reject("then error");
return Promise.resolve(val*2);
})
.catch(err => { console.log(err);
return Promise.reject("you won't see this");
})
.then(val => console.log("Both the promise and the first then stage worked fine and resulted: ", val));
最后一个then
阶段回调将只在第一个then
阶段的第一个承诺和第二个承诺解析时被调用。