在此之前和之后放置捕获 [英] Placement of catch BEFORE and AFTER then

查看:19
本文介绍了在此之前和之后放置捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解将 .catch BEFORE 和 AFTER 放在嵌套 promise 中的区别.

I have trouble understanding the difference between putting .catch BEFORE and AFTER then in a nested 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失败,如果数字是>,则test2失败;如果数字不是 100,则 10 和 test3 失败.在这种情况下,test2 只是失败了.

The behavior of each function is as follow, test1 fail if number is <0 test2 fails if number is > 10 and test3 fails if number is not 100. In this case test2 is only failing.

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

I tried to run and make test2Async fail, both BEFORE and AFTER then behaves the same way and that is not executing the test3Async. Can somebody explain to me the main difference for placing catch in different places?

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

In each function I console.log('Running test X') in order to check if it gets executed.

这个问题是因为我之前发布的帖子如何将嵌套回调变成promise?.我认为这是一个不同的问题,值得发布另一个主题.

This question arises because of the previous thread I posted How to turn nested callback into promise?. I figure it is a different problem and worth posting another topic.

推荐答案

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

So, basically you're asking what is the difference between these two (where p is a promise created from some previous code):

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

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

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

There are differences either when p resolves or rejects, but whether those differences matter or not depends upon what the code inside the .then() or .catch() handlers does.

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

In the first scheme, when p resolves, the .then() handler is called. If that .then() handler either returns a value or another promise that eventually resolves, then the .catch() handler is skipped. But, if the .then() handler either throws or returns a promise that eventually rejects, then the .catch() handler will execute for both a reject in the original promise p, but also an error that occurs in the .then() handler.

在第二种方案中,当 p 解析时,会调用 .then() 处理程序.如果 .then() 处理程序抛出或返回一个最终拒绝的承诺,则 .catch() 处理程序无法捕获它,因为它在链中的前面.

In the second scheme, when p resolves, the .then() handler is called. If that .then() handler either throws or returns a promise that eventually rejects, then the .catch() handler cannot catch that because it is before it in the chain.

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

So, that's difference #1. If the .catch() handler is AFTER, then it can also catch errors inside the .then() handler.

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

Now, in the first scheme, if the promise p rejects, then the .then() handler is skipped and the .catch() handler will be called as you would expect. What you do in the .catch() handler determines what is returned as the final result. If you just return a value from the .catch() handler or return a promise that eventually resolves, then the promise chain switches to the resolved state because you "handled" the error and returned normally. If you throw or return a rejected promise in the .catch() handler, then the returned promise stays rejected.

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

In the second scheme, if the promise p rejects, then the .catch() handler is called. If you return a normal value or a promise that eventually resolves from the .catch() handler (thus "handling" the error), then the promise chain switches to the resolved state and the .then() handler after the .catch() will be called.

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

So that's difference #2. If the .catch() handler is BEFORE, then it can handle the error and allow the .then() handler to still get called.

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

Use the first scheme if you want just one .catch() handler that can catch errors in either the original promise p or in the .then() handler and a reject from p should skip the .then() handler.

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

Use the second scheme if you want to be able to catch errors in the original promise p and maybe (depending upon conditions), allow the promise chain to continue as resolved, thus executing the .then() handler.

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

There's one other option to use both callbacks that you can pass to .then() as in:

 p.then(fn1, fn2)

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

This guarantees that only one of fn1 or fn2 will ever be called. If p resolves, then fn1 will be called. If p rejects, then fn2 will be called. No change of outcome in fn1 can ever make fn2 get called or vice versa. So, if you want to make absolutely sure that only one of your two handlers is called regardless of what happens in the handlers themselves then you can use p.then(fn1, fn2).

这篇关于在此之前和之后放置捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆