【问题标题】: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 而不是 rethrowing。

标签: javascript promise


【解决方案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() 拒绝,您需要在.thenresolvedrejected 部分发生错误

鉴于此,如果您返回一个被拒绝的承诺,它将拒绝:

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)
猜你喜欢
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多