【问题标题】:Difference of exception and unfulfilled promise?例外与未兑现承诺的区别?
【发布时间】:2021-09-13 23:23:10
【问题描述】:

我正在阅读有关错误处理的内容,书上说

如果在 Promises then 处理函数中发生抛出,那么它是 拒绝。考虑异常和拒绝的一种方式是,异常是同步错误,而拒绝是异步错误。

问题

  • 书上写了rejection,但那不应该是unfulfilled吗?
  • 我的印象是throw 总是例外?
  • 为什么只有同步代码才有例外?

【问题讨论】:

  • 那是什么书?请注意它说“一种思考……的方式”,即这是一种(有用的)简化,而不是所有技术细节的终极真理。
  • @Bergi Linux 基础课程“NODE.JS 应用程序开发 (LFW211)”。这本书感觉像是从许多不同的来源复制/粘贴,并没有以任何方式真正完善。
  • "这是拒绝" - 我不会这么说。抛出的值在then 处理函数中仍然是一个异常。但它会导致拒绝then() 调用返回的承诺。
  • 一旦你await 被拒绝的承诺,你又会得到一个例外......所以那里的术语有点流利。

标签: javascript node.js ecmascript-6


【解决方案1】:

一个未履行的承诺只是一个尚未履行的承诺,即使它不拒绝也是很有可能的。例如:

const prom = new Promise((resolve) => {
  // code here that never calls `resolve`
});

这是一个永远不会实现的承诺 - 但它也不会拒绝。

“未实现”的 Promise 不一定像上面那样永远挂起 - 它只是一个尚未解决的 Promise。

抛出总是异常?

在某种程度上,是的,尽管它在 Promise 中的行为有所不同 - 它不会导致 error 事件。相反,它会尝试在它当前所在的 Promise 链中查找 .catch 处理程序,如果找不到,则会触发 unhandledrejection 事件。

为什么只有同步代码才有例外?

这就是语言的设计方式。

【讨论】:

  • 我发现这篇文章也解释了术语。 stackoverflow.com/a/29269515/256439 。我不确定我是否理解 throw 那么是什么。扔和还的区别是什么?
  • 在 Promise 内抛出会导致 Promise 以抛出的值拒绝。在 Promise 中返回会导致 Promise 与返回的值一起解决 - 即使返回的是错误。 (例如 return new Error() 是可能的 - 它会进入 Promise 链的 .then,而不是 .catch
  • 非常感谢 =)
【解决方案2】:

我认为您需要了解需要拒绝的原因,以及它试图解决的问题。考虑一个简单的例子:

try {
  iDoNotExist
} catch(e) {
  //e ReferenceError
}

很简单,正在评估代码并“尝试”错误。有这样一个错误,好吧,它被抓住了。

现在,如果我们把它改成这样会怎么样:

try {
  setTimeout(function(){ iDoNotExist }, 1000);
} catch(e) {
  //e ReferenceError
}

如果您运行此代码,您会注意到您的 javascript 环境会发出错误。它不是在这里被抓住的。为什么?因为引发错误的代码在“尝试”时没有运行,只有 setTimeout 函数只是简单地调度函数,并且该函数正在完成它的工作,它正在正确地调度它。反过来,这也是为什么很多人在尝试访问异步函数的产物时会出错的原因。例如

let result;
setTimeout(() => result = true, 1000);
console.log(result) // Why is this undefined? - Famous last question

输入 Promise 进行救援,它不仅可以让您恢复通常会使用 return 的值,还可以让您恢复在所述异步操作中发生的任何潜在错误。为您提供与同步代码相似的语义(与async 函数配对时更是如此)。

所以,我会说拒绝是对例外的补充。在存在异步边界时保留您的程序流程(就像已实现的承诺一样保留函数组合)。

至于你所说的未完成...有几件事。 未完成 表示“未完成”。从技术上讲,被拒绝的承诺是未实现的承诺。然而,一个未解决的承诺(一个处于待处理状态的承诺)也是一个未实现的承诺。技术上。

大多数人会想到后者,但实际上两者都可能。主要是因为它来自“实现”和“解决”可以互换使用的时代(这是错误的)。但也因为这通常是承诺解决方案的预期结果。

在任何情况下,未解决的承诺都不是被拒绝的承诺。未解决的承诺处于过渡状态,在这种状态下,它可以转变为已履行的承诺或被拒绝的承诺。

【讨论】:

  • ……一个承诺可以解决,但仍在等待中……
  • @Bergi Oof,那个场景是什么?这是 ES6 承诺的一个怪癖吗?
  • 不,所有的 Promise 都会这样做,当你用另一个未决的 Promise 解决一个 Promise 时。
  • 哦,我一直认为承诺已解决,直到它解决的承诺得到解决,但我想你可以这样看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多