javascript - 之前和之后的捕获位置

标签 javascript node.js promise bluebird

我很难理解把 .catch 放在一起的区别。 BEFORE 和 AFTER then 在嵌套的 Promise 中。

备选方案 1:

test1Async(10).then((res) => {
  return test2Async(22)
    .then((res) => {
      return test3Async(100);
    }).catch((err) => {
      throw "ERROR AFTER THEN";
    });
}).then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});

备选方案 2:

test1Async(10).then((res) => {
   return test2Async(22)
     .catch((err) => {
        throw "ERROR BEFORE THEN";
      })
      .then((res) => {
        return test3Async(100);
      });
  }).then((res) => {
    console.log(res);
  }).catch((err) => {
    console.log(err);
  });

每个函数的行为如下,如果数字为<0,则test1失败如果数字为 > 10,则 test2 失败如果 number 不是 100,则 test3 失败.在这种情况下 test2 只是失败了。

我尝试运行并使 test2Async 失败,然后 BEFORE 和 AFTER 的行为方式相同,并且没有执行 test3Async。有人可以向我解释将捕获物放在不同地方的主要区别吗?

在每个函数中我 console.log('Running test X')为了检查它是否被执行。

这个问题的出现是因为我之前发布的帖子 How to turn nested callback into promise? .我认为这是一个不同的问题,值得发布另一个主题。

最佳答案

所以,基本上你是在问这两者有什么区别(其中 p 是从以前的代码创建的 promise ):

return p.then(...).catch(...);

return p.catch(...).then(...);

p 解决或拒绝时存在差异,但这些差异是否重要取决于 .then().catch() 中的代码处理程序会。

p 解析后会发生什么:

在第一个方案中,当 p 解析时,调用 .then() 处理程序。如果该 .then() 处理程序返回一个值或另一个最终解决的 promise ,则 .catch() 处理程序将被跳过。但是,如果 .then() 处理程序抛出或返回最终拒绝的 promise ,则 .catch() 处理程序将执行原始 promise 中的拒绝p,但也是在 .then() 处理程序中发生的错误。

在第二种方案中,当 p 解析时,调用 .then() 处理程序。如果该 .then() 处理程序抛出或返回最终拒绝的 promise ,则 .catch() 处理程序无法捕获它,因为它在链中位于它之前。

所以,这就是差异 #1。如果 .catch() 处理程序是 AFTER,那么它也可以在 .then() 处理程序内捕获错误。

p 拒绝时会发生什么:

现在,在第一个方案中,如果 promise p 拒绝,则 .then() 处理程序将被跳过并且 .catch() 处理程序将按照您的预期调用。您在 .catch() 处理程序中执行的操作决定了作为最终结果返回的内容。如果您只是从 .catch() 处理程序返回一个值或返回一个最终解决的 promise ,那么 promise 链将切换到已解决状态,因为您“处理”了错误并正常返回。如果您在 .catch() 处理程序中抛出或返回被拒绝的 Promise,则返回的 Promise 将保持被拒绝。

在第二种方案中,如果 promise p 拒绝,则调用 .catch() 处理程序。如果您返回一个正常值或最终从 .catch() 处理程序解决的 promise (因此“处理”错误),则 promise 链切换到已解决状态和 .catch() 之后的 then() 处理程序将被调用。

这就是区别 #2。如果 .catch() 处理程序是 BEFORE,那么它可以处理错误并允许 .then() 处理程序仍然被调用。

何时使用:

如果您只需要一个 .catch() 处理程序,可以在原始 promise p.then( ) 处理程序和来自 p 的拒绝应该跳过 .then() 处理程序。

如果您希望能够捕获原始 promise p 中的错误,并且可能(取决于条件)允许 promise 链继续解析,则使用第二种方案,从而执行 .then() 处理程序。

其他选项

还有另一个选项可以同时使用两个回调,您可以将其传递给 .then(),如下所示:

 p.then(fn1, fn2)

这保证只有 fn1fn2 之一将被调用。如果 p 解析,则 fn1 将被调用。如果 p 拒绝,则将调用 fn2fn1 中的结果没有任何变化可以使 fn2 被调用,反之亦然。因此,如果您想绝对确保只调用两个处理程序中的一个,而不管处理程序本身发生了什么,那么您可以使用 p.then(fn1, fn2)

关于javascript - 之前和之后的捕获位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42013104/

相关文章:

javascript - 使用 JSON 对象中的数据进行动态货币转换

javascript - 将属性保留到 Express 中的以下中间件

javascript - Nodejs 读取数据库查询会引发单个字段错误

javascript - 我如何交错/合并异步迭代器?

javascript - 如何在 Bower 中注册本地 git 包?

javascript - 在 C# 中将 (Javascript)TypedArray 字符串转换为 byteArray 的最佳方法

javascript - Moment .isAfter 没有正确返回

node.js - 囫囵吞枣。如何在不重复行的情况下合并文件

javascript - 延迟链崩溃浏览器

javascript - $scope.$watch value 包含在 Promise $q.when(value) 中