我有两个承诺,彼此独立,我希望在两个承诺完成之后做最后一步(拒绝或结算)。
$ q.all()不能被使用,因为我希望最终总是执行(两个承诺只执行一次),即使任何承诺拒绝
一个解决方案可能是拥有一个计数器并具有finallyHandler函数,以便在两个promise解析/拒绝时执行它。
var count = 0;
function finallyHandler() {
if ( ++count === 2 ) {
doStuff();
count = 0;
}
}
firstPromise.finally(finallyHandler);
secondPromise.finally(finallyHandler);
这可行但看起来不对。
有没有更好的方法呢?
答案 0 :(得分:1)
Promise.all(iterable)将执行您正在寻找的内容。但是,请查看浏览器兼容性,因为Internet Exploer不支持此方法。来自文档:
Promise.all(iterable)方法返回一个解析时间的promise 可迭代参数中的所有promise都已解决或拒绝 由于第一个通过的拒绝承诺的原因。
使用您的代码示例(具有失败行为),它看起来像这样:
Promise.all([firstPromise, secondPromise]).then(values => {
finallyHandler();
}, reason => {
finallyHandler();
});
即使失败块与成功块相同,成功块仅在所有承诺成功完成后运行,并且失败块运行一次(并且仅运行一次)遇到第一次失败。
参考:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
答案 1 :(得分:0)
firstPromise().catch().secondPromise().catch().then(//what you want)
上述承诺链可以实现这一目标。在所有情况下都会调用最终then
。 catch
会传播承诺拒绝。
答案 2 :(得分:0)
答案 3 :(得分:0)
通常$q.all
在第一个被拒绝的承诺上被拒绝,并且不会等待其他承诺。要等待所有承诺解决已履行或已拒绝,请为每个承诺制作弹性版本,然后对这些承诺使用$q.all
:
var resiliantFirstPromise = firstPromise.catch(e => "CONVERTED");
var resiliantSecondPromise = secondPromise.catch(e => "CONVERTED");
$q.all([resiliantFirstPromise, resiliantSecondPromise])
.then(() => {
console.log("Both promises have resolved");
});
通过向.catch
方法返回一个值,每个被拒绝的承诺都会返回一个派生的承诺,该承诺已经转换为履行的承诺。由于两个派生的承诺都没有被拒绝,{ {1}}将等待两个承诺得到解决(完成或拒绝)。