【问题标题】:Is Promise.then(a, b) the same as Promise.then(a).catch(b)? [duplicate]Promise.then(a, b) 和 Promise.then(a).catch(b) 一样吗? [复制]
【发布时间】:2019-01-12 12:34:19
【问题描述】:

两者有什么区别

?

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

除了代码可读性之外,我是否更喜欢使用其中一种?

【问题讨论】:

    标签: javascript promise es6-promise


    【解决方案1】:

    它们在处理 then() 回调中的错误的方式上有所不同,在某些情况下,这可能是一个足够大的差异,大多数人建议仅使用 catch()

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

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

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

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

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

    您可以同时使用这两种方法,这将在then() 回调中捕获拒绝和错误,但这会使事情变得比您可能需要的更加混乱,除非您有一个特殊的用例来区分这两种错误。例如哪个处理程序处理哪些错误:

    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))

    【讨论】:

    • 实际上,想要处理来自某个 Promise 的拒绝是很常见的,不仅仅是“一些测试场景”。
    • 我非常喜欢这个答案,它很好地展示了两种情况之间的差异。谢谢!
    【解决方案2】:

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

    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() 的情况下也会重现上述场景。

    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));

    【讨论】:

    • 建议您在需要时使用.catch(),但并非总是如此。
    • @Ry- 更新了答案,谢谢:-)
    • 你的例子没有意义:即使你使用了两个catch 块,下一个then 回调也会被执行。这里的修复是删除一个错误处理程序,而不是使用不同的then 语法。不,正如@Ry- 所说:一般不建议使用catch
    • 那么你想说的是,如果第一个then() 块只有一个参数,并且承诺被拒绝,那么第二个then(func) 块会被跳过吗?如果是这样,我认为它可以有更好的措辞,但无论如何感谢你为我指明了正确的方向!
    【解决方案3】:

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

    此外,如果您想一一调用一些异步函数,但如果抛出一些错误需要立即中断(不希望以下函数继续运行)。您只需要在决赛中放 1 个接球即可。在这种情况下,我们不能使用第一种样式。

    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 })
    

    在上面的例子中。可以看到,任何一个函数async失败,程序都会跳过后面的函数直接catch。

    【讨论】:

    • 它们不一样。
    • 怎么不一样?你可以用一种风格举个例子,我可以用另一种风格解决它,结果和你预期的一样。
    • 该问题询问p.then(a, b)p.then(a).catch(b) 之间的区别。就是这样,这就是全部。用“我认为这两种方式是相同的”来回答它是错误的。请参阅投票赞成的答案,了解它们有何不同。
    • 我回答了一般用法都差不多。区别在于编码风格。而且我还陈述了我认为只能应用 catch() 的唯一情况。那么你还想要什么?
    • 这不是优化。行为上有一个实际而重要的区别。
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 2021-10-06
    • 2019-10-27
    • 2013-11-19
    • 2011-06-13
    • 2013-06-25
    • 2012-12-29
    相关资源
    最近更新 更多