为啥在 Promise.all() 之后不调用 onRejected,其中包含在数组中的 Promise.reject() 传递给 Promise.all()?
Posted
技术标签:
【中文标题】为啥在 Promise.all() 之后不调用 onRejected,其中包含在数组中的 Promise.reject() 传递给 Promise.all()?【英文标题】:Why is onRejected not called following Promise.all() where Promise.reject() included in array passed to Promise.all()?为什么在 Promise.all() 之后不调用 onRejected,其中包含在数组中的 Promise.reject() 传递给 Promise.all()? 【发布时间】:2016-05-04 16:22:35 【问题描述】:给定
var promises = [Promise.resolve("a"), Promise.reject("b")];
Promise.all(promises.map(function(p, index)
return p.then(function(data)
console.log("inside .map()", data, "index", index)
return data
, function(err)
console.log(err);
return err
)
))
.then(function(complete)
console.log("all promises after .map()", complete)
, function(err)
console.log("err", err)
)
为什么onRejected
没有在.then(onFulfilled, onRejected)
之后调用Promise.all()
?
jsfiddle https://jsfiddle.net/9gprLc7q/
https://jsfiddle.net/9gprLc7q/
【问题讨论】:
因为您没有处理映射中的错误,所以您返回的仍然是已解决的承诺。如果你这样做Promise.reject(err)
,它将正常工作。
即使不重复也密切相关(但不是一个明显的):Chained promises not passing on rejection。你 return err
而不是 rethrow
ing。
【参考方案1】:
您需要了解,处理拒绝会导致将承诺重新推上成功之路。解决此问题的一种方法是重新抛出故障处理程序,如下所示:
var promises = [Promise.resolve("a"), Promise.reject("b")];
Promise.all(promises.map(function(p, index)
return p.then(function(data)
console.log("inside .map()", data, "index", index)
return data
, function(err)
console.log(err);
// RE-THROW!!
throw err;
)
))
.then(...
如果拒绝处理程序的目的仅仅是记录,那么您可以将其移出链:
Promise.all(promises.map(function(p, index)
// MOVE ERROR HANDLER OUTSIDE OF CHAIN
p.catch(function(e) console.log(e); );
return p.then(function(data)
console.log("inside .map()", data, "index", index)
return data
)
))
.then(...
【讨论】:
我谈到了这一点,但把它删掉了。感谢您的措辞比我做得更好:D【参考方案2】:你在这里真正做的是这样的:
https://jsfiddle.net/9gprLc7q/5/
var notRejectedPromise =
Promise.reject("b")
.then((resolved) => resolved, (err) => err)
var promises = [Promise.resolve("a"), notRejectedPromise];
Promise.all(promises)
.then(function(complete)
console.log("all promises after .map()", complete)
, function(err)
console.log("err", err)
)
但是决定通过返回任何 err
来处理错误部分,您返回了一个字符串。这不是拒绝的理由。
要真正导致Promise.all()
拒绝,您需要在.then
的resolved
或rejected
部分发生错误
鉴于此,如果您返回一个被拒绝的承诺,它将拒绝:
https://jsfiddle.net/9gprLc7q/3/
console.log(err)
到
return Promise.reject(err)
您也可以抛出错误:https://jsfiddle.net/9gprLc7q/2/
console.log(err)
到
throw new Error(err)
【讨论】:
为什么在.map()
删除.then()
会返回预期结果jsfiddle.net/9gprLc7q/4?为什么被拒绝的Promise
转换为已解决的Promise
?
@guest271314 这是因为您从未将.then
附加到被拒绝的承诺上。所以现在不是返回"b"
,这不是拒绝,而是返回自己Promise.reject("b")
,这是一个拒绝的值。
@guest271314 也许这会帮助jsfiddle.net/9gprLc7q/5。当您在原始代码中执行 return err
时,错误部分返回一个字符串而不是 Promise.reject
仅使用 throw err
jsfiddle.net/9gprLc7q/6 返回预期结果,不使用 new Error(err)
@guest271314 你去***.com/questions/9156176/…:D以上是关于为啥在 Promise.all() 之后不调用 onRejected,其中包含在数组中的 Promise.reject() 传递给 Promise.all()?的主要内容,如果未能解决你的问题,请参考以下文章
与 Promise.all() 中的解析相比,为啥在 while 循环中单独解析 Promise 数组时解析更慢? [复制]
React Native 为啥我的代码在完成任务之前执行? Promise.all().then() 异步问题
为啥即使我 .catch() Promise.all() 也会抛出异常?