【问题标题】:promise got resolved instead of rejected, even the inner promise returned承诺得到解决而不是被拒绝,甚至内部承诺也返回
【发布时间】:2021-12-20 13:52:14
【问题描述】:

对于下面的承诺链

new Promise(r=>r('b').then(()=>Promise.reject('x'))).catch(err=>console.log({error}))

返回内部承诺,因此它应该冒泡并被外部catch 块捕获并将错误记录到控制台。

但是,它得到了解决。

Promise {<fulfilled>: 'b'}

如何通过外部 catch 块捕获内部承诺?

【问题讨论】:

  • r('b') 不返回承诺。您不能在其上链接 .then()。好像你放错了一些括号:new Promise(r=&gt;r('b')).then(()=&gt;Promise.reject('x')).catch(err=&gt;console.log({error}))

标签: javascript promise es6-promise


【解决方案1】:

r(通常称为resolve)不返回承诺,因此在其上调用.then 是错误的。通常,如果在 Promise 执行器函数(您传递的函数 new Promise)中抛出错误,则正在创建的 Promise 会因该错误而被拒绝。但是既然你已经调用了resolve,你已经履行"b"的承诺,一旦履行就不能改变为被拒绝,所以执行期间发生的错误被压制了. (这是更一般规则的一个具体案例,即一旦一个承诺被解决 [与结果相关联],它就不能以不同的方式解决。一个承诺可以在 [尚未] 被履行的情况下解决,但实现它是解决它的一种方法。如果你不是 100% 理解这个承诺术语,请查看 my blog post here 解释它。)

如果您想将您正在创建的承诺解析为另一个承诺,请将其传递 resolve 函数:

new Promise(resolve => {
    resolve(Promise.reject(new Error("x")));
})
.then(value => console.log("value", value))
.catch(error => console.error("error", error.message));

那个具体例子就是Explicit promise construction antipattern的例子(我们应该直接使用Promise.reject的promise),但是如果你在promise executor中有分支逻辑和一些分支不涉及承诺,您可能会做类似的事情(尽管从风格上讲,抛出错误或调用传递给执行程序的 reject 函数对我来说更有意义)。

【讨论】:

  • FWIW,我在最近一本书 JavaScript: The New Toys 的第 8 章中详细介绍了 Promise。如果您有兴趣,请在我的个人资料中链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 2015-12-25
  • 2018-04-02
  • 2023-03-26
  • 2015-09-04
  • 2015-09-27
  • 2018-05-09
相关资源
最近更新 更多