关于javascript:Promise.then(a,b)和Promise.then(a).catch(b)一样吗?

Is Promise.then(a, b) the same as Promise.then(a).catch(b)?

本问题已经有最佳答案,请猛点这里访问。

有什么区别

  • 1
    myPromise.then(a, b)
  • 1
    myPromise.then(a).catch(b)

无论myPromise的内容和状态以及函数ab的实现如何,两个JavaScript表达式总是会产生相同的结果吗?

除了代码可读性之外,我是否应该更喜欢使用一个而不是另一个?


建议使用catch(),因为当我们在promise链中使用myPromise.then(a, b)时,接下来,即使promise被拒绝,block也会一直执行。这是因为promise链认为我们已经清除了错误处理程序中的错误。
看下面的例子:
即使我们reject()下一个块然后执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function asyncFun(a,b){
  return new Promise((resolve, reject)=>{
      if(typeof a ==="number" && typeof b ==="number")
        resolve(a + b);
      else
        reject("invalid data!!");
  });
}
asyncFun(2,'4').then((response)=>{
  console.log(response);
  return response;
}, (error)=>{
  console.log(error);
}).then((response)=>{
  console.log("console 2",response)
}, (error)=>{
  console.log(error);
});

如果我们在promise链的末尾只使用一个错误处理程序catch(),就不会发生这种情况:请注意正如Bergi指出的那样,即使在多个catch()的情况下也会重现上述场景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function asyncFun(a,b){
  return new Promise((resolve, reject)=>{
      if(typeof a ==="number" && typeof b ==="number")
        resolve(a + b);
      else
        reject("invalid data!!");
  });
}
asyncFun(2,'4').then((response)=>{
  console.log(response);
  return response;
}).then((response)=>{
  console.log("console 2",response)
}).catch((err)=> console.log(err));


它们处理then()回调中的错误的方式不同,在某些情况下,这可能是一个非常显着的差异,大多数人建议只使用catch()

例如,使用catch(),您可以捕获此错误:

1
2
3
4
5
Promise.resolve('test')
.then(r => {
  throw("whoops")
})
.catch(e => console.log("caught error:", e))

使用then(a,b)样式你不能:

1
2
3
4
Promise.resolve('test')
.then(r => { throw("whoops")},
      e => console.log("caught error?", e))
// unhandled rejection (you'll need to look in the console)

除了一些测试场景之外,很难想到这种行为是首选的用例。

您可以同时使用两者,这将在then()回调中捕获拒绝和错误,但这会使您比您可能需要的更令人困惑,除非您有一个特殊用例来区分这两种错误。例如哪个处理程序处理哪些错误:

1
2
3
4
5
6
7
8
9
Promise.reject("rejected")
.then(r => {throw("whoops")},
     e => console.log("Promise 1: caught error in second function:", e))
.catch(e=> console.log("Promise 1: caught error in catch", e))

Promise.resolve("rejected")
.then(r => {throw("whoops")},
     e => console.log("Promise 2: caught error in second function:", e))
.catch(e=> console.log("Promise 2: caught error in catch", e))


我认为,这两种方式是相同的。但是,我更喜欢使用async().then().catch(),因为它更容易阅读。

而且,如果你想逐个调用一些异步函数,但需要立即中断(不希望以下函数继续运行)如果抛出一些错误。你需要在决赛中只投入一次。在这种情况下,我们不能使用第一种风格。

1
2
3
4
5
asyncA()
    .then((val) => asyncB(val))
    .then((val) => asyncC(val))
    .then((val) => asyncD(val))
    .catch(() => { /* any of asyncA, asyncB, asyncC, asyncD will goes directly here if throwing error })

在上面的例子中。你可以看到,任何函数异步失败,程序将跳过以下函数并直接捕获。