我有以下函数返回Promise:
function someFn() {
// Making use of Bluebird's Promise.all()
return Promise.all([promise1, promise2]).then(function(results) {
results.forEach(function(result) {
return promiseReturningFn(); // Returns a Promise
});
}).catch(function(err) {
console.log(err);
});
}
关于这段代码,我有两个问题:
在任何
forEach()
迭代的promiseReturningFn()
拒绝的情况下,catch()
语句会捕获拒绝吗?如果第一次迭代的
promiseReturningFn()
拒绝,迭代将停止,这意味着不会为结果数组中的第二个元素调用回调吗?如果是这样,此失败后控制流将传递给catch()
语句吗? 最佳答案
关于您的两个问题:
在任何forEach()迭代的promiseReturningFn()拒绝的情况下,catch()语句会捕获拒绝吗?
不,因为您没有在return
回调中使用then
承诺,但在forEach
回调中使用了后者,而后者没有效果-这样的返回值被遗忘了。
如果第一次迭代的promiseReturningFn()拒绝,则迭代将停止,这意味着不会为结果数组中的第二个元素调用回调吗?如果这是真的,那么在失败之后将控制流传递给catch()语句吗?
不,迭代不会停止。您甚至都不知道同步拒绝,因为此信息仅异步可用(暂时忽略bluebird
允许同步检查)。
假设您允许promiseReturningFn
在另一个尚未解决的已承诺中已经执行时,这可能是应该如何编码的:
function someFn() {
// Making use of Bluebird's Promise.all()
return Promise.all(
[promise1, promise2].map(p => p.then(promiseReturningFn))
}).catch(function(err) {
console.log(err);
});
}
或者,如果在开始为它们执行
promiseReturningFn
之前确实需要所有承诺的数组,请执行以下操作:function someFn() {
// Making use of Bluebird's Promise.all()
return Promise.all([promise1, promise2]).then(results => {
return Promise.all(results.map(promiseReturningFn));
}).catch(function(err) {
console.log(err);
});
}
无论哪种情况,现在您的两个问题的答案是:
是的,如果任何一个内部承诺都被拒绝,则将执行
catch
回调。不,迭代不会停止,因为Promise的结果仅是异步知道的,因此届时循环(
map
)将已经完全执行。要使第二个问题的答案为“是”,并在先前返回的诺言被拒绝时停止调用
promiseReturningFn
,您必须对它们进行序列化,等待一个诺言兑现,然后再次调用promiseReturningFn
:function someFn() {
// Making use of Bluebird's Promise.all()
return Promise.all([promise1, promise2]).then(results => {
return (function loop(i, p) {
return i >= results.length ? p
: p.then(_ => loop(i+1, promiseReturningFn(result[i])));
})(0, Promise.resolve());
}).catch(function(err) {
console.log(err);
});
}
关于javascript - arr.forEach()语句的回调内的promise拒绝会停止迭代吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44122950/