【问题标题】:What errors do catch() and "error handler" of then(successHandler, failureHandler) detect?then(successHandler, failureHandler) 的 catch() 和“错误处理程序”检测到哪些错误?
【发布时间】:2019-04-22 05:13:46
【问题描述】:

我正在学习 Promises,以便在尝试使用 Firebase 之前更好地理解。我是新手,我一直在阅读有关catch() 的以下内容:

  • Link one:有一些练习的文章
  • Link two:关于为什么我们在 Promise 链之后总是需要 catch() 的问题
  • Link three:关于catch()then() 区别的问题

根据我的阅读,我得出以下结论:

  • catch() 在每个 Promise 链接中都是必需的,以防出现“意外异常”。我的thenfailureHandler 似乎可以检测到这些“意外异常”。但是,它无法将“正常故障”与这些类型的故障区分开来。我认为其中一个“意外异常”是当您尝试访问 null 元素的某些属性时。
  • 似乎我也可以链接then(successHandler, failureHandler),然后继续使用catch() 块以进行更精细的控制,如link two 中所述。当我想在某些事情失败时做其他事情(在这种情况下是“正常失败”,而不是“意外异常”)并将被拒绝的 Promise 传递给下一个 then 进行处理时,这很有用,因此可能会产生非常不同的结果结果是失败的部分成功了。我还可以在链的末尾使用catch() 来捕获“意外异常”,以防我的successHandlerfailureHandler 内部出现故障。

从我的结论中可以看出,我对可能发生的错误知之甚少。我提到null 异常是“意外异常”的示例之一(这个假设是否正确?)。但是,failureHandler 还检测到哪些其他错误,catch() 检测到哪些其他“意外异常”?

我在上面也提到过,[then] 无法区分正常故障和这些类型的故障。那是对的吗?如果是,为什么它很重要?

编辑

在阅读了更多之后,似乎如果一个 Promise 在链的顶部被拒绝,则下面的 thens 将被忽略,我立即转到 catch() 块。这意味着我上面的结论:当我想在某些事情失败时做其他事情并将被拒绝的 Promise 传递给下一个 then 进行处理时,这很有用 是不正确的。如果是这种情况,如果我的链末尾已经有一个catch(),我的每个then 块都不再需要一个failureHandler。但是在链接三中提到了:

争论是通常你想在每一步中捕获错误 处理,并且您不应该在链中使用它。这 期望是您只有一个最终处理程序来处理所有 错误 - 当你使用“反模式”时,一些错误 then-callbacks 不被处理。

不过,这种模式其实很有用:当你想处理 正是在这一步中发生的错误,你想做 当没有发生错误时完全不同的东西 - 即当 错误是不可恢复的。请注意,这是在扩展您的控制权 流动。当然,有时这是需要的。

我的结论是,被拒绝的 Promise 将传递给下一个 then 进行处理,因为我阅读了上述内容。那么当没有错误发生时——即当错误不可恢复时你想做完全不同的事情是什么意思?

【问题讨论】:

    标签: javascript promise


    【解决方案1】:

    MDN 我了解到声明拒绝处理程序的两种方法之间没有真正的区别。

    为了成功,很明显我们将到达履行处理程序:

    var promise = new Promise(function(resolve, reject) {
      setTimeout(function() {
        resolve('success');
      }, 300);
    }).then(function(success) {
      console.log(0, success)
    }, function(failure) {
      console.log(1, failure)
    }).catch(function(failure) {
      console.log(2, failure)
    });

    对于拒绝,我们将到达第一个拒绝处理程序。
    拒绝承诺时:

    var promise = new Promise(function(resolve, reject) {
      setTimeout(function() {
        reject('failure');
      }, 300);
    }).then(function(success) {
      console.log(0, success)
    }, function(failure) {
      console.log(1, failure)
    }).catch(function(failure) {
      console.log(2, failure)
    });

    抛出错误时:

    var promise = new Promise(function(resolve, reject) {
      throw "throw";
    }).then(function(success) {
      console.log(0, success)
    }, function(failure) {
      console.log(1, failure)
    }).catch(function(failure) {
      console.log(2, failure)
    });

    注意catch 块是如何被忽略的,因为它被链接到第一个处理程序的承诺(履行或拒绝)。
    如果我们将其更改为拒绝或重新抛出,我们将到达catch 中的处理程序。

    var promise = new Promise(function(resolve, reject) {
      throw "re-throw";
    }).then(function(success) {
      console.log(0, success)
    }, function(failure) {
      console.log(1, failure)
      throw failure;
    }).catch(function(failure) {
      console.log(2, failure)
    });

    上面的链接中的这张图片很好地描述了它。

    【讨论】:

      猜你喜欢
      • 2020-01-28
      • 1970-01-01
      • 2017-08-27
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 2019-05-19
      • 2015-11-17
      • 2023-04-09
      相关资源
      最近更新 更多