我有以下函数返回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()
语句? 答案 0 :(得分:3)
关于你的两个问题:
- 在任何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);
});
}