【问题标题】:How does the 'catch' work in a native Promise chain?'catch' 在原生 Promise 链中是如何工作的?
【发布时间】:2016-03-17 07:46:20
【问题描述】:

在 Chrome 或 Firefox 的控制台选项卡上尝试这段代码

var p = new Promise(function(resolve, reject) {
    setTimeout(function() {
        reject(10);
    }, 1000)
})

p.then(function(res) { console.log(1, 'succ', res) })
.catch(function(res) { console.log(1, 'err', res) })
.then(function(res) { console.log(2, 'succ', res) })
.catch(function(res) { console.log(2, 'err', res) })

结果是

1 "err" 10
2 "res" undefined

我尝试了许多其他示例,但似乎第一个 then() 返回了一个始终解决且从不拒绝的承诺。我在 Chrome 46.0.2490.86 和 Firefox 42.0 上试过这个。为什么会这样?我以为then()catch() 可以链接多次?

【问题讨论】:

标签: javascript google-chrome firefox promise


【解决方案1】:

就像在同步代码中一样:

try { 
    throw new Error();
} catch(e) {
    console.log("Caught");
}
console.log("This still runs");

在异常处理后运行的代码将运行 - 这是因为异常是一种错误恢复机制。通过添加该 catch,您表示该错误已得到处理。在同步情况下,我们通过重新抛出来处理:

try { 
    throw new Error();
} catch(e) {
    console.log("Caught");
    throw e;
}
console.log("This will not run, still in error");

Promise 的作用类似:

 Promise.reject(Error()).catch(e => {
      console.log("This runs");
      throw e;
 }).catch(e => {
      console.log("This runs too");
      throw e;
 });

作为提示 - 永远不要拒绝非Errors,因为你会丢失很多有用的东西,比如有意义的堆栈跟踪。

【讨论】:

    【解决方案2】:

    为什么会这样?我以为 then() 和 catch() 可以链多次?

    @Benjamin 是对的,+1,但换句话说,这些是规则:

    • 如果您多次添加then,您将链接应按顺序调用的方法,直到引发异常。 then 链中的异常必须由在then 之后声明的catch 处理。如果then后面没有catch,则会触发此错误:Uncaught (in promise) Error(…)
    • 如果您多次添加catch,则您链接的方法应该在出现问题时调用(在之前的then 函数中)。但是,链中的第二个 catch 只有在第一个重新抛出异常时才会被调用,以此类推。
    • catch 被触发时,链会在catch 之后声明的下一个then 处恢复。

    【讨论】:

      猜你喜欢
      • 2021-07-28
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      相关资源
      最近更新 更多