在承诺捕获中重新抛出错误

2022-08-30 05:34:38

我在教程中找到了以下代码:

promise.then(function(result){
    //some code
}).catch(function(error) {
    throw(error);
});

我有点困惑:catch呼叫是否完成了任何事情?在我看来,它没有任何影响,因为它只是抛出与捕获相同的错误。我基于常规尝试/捕获的工作原理。


答案 1

在你展示时,裸体的接球和投掷是没有意义的。除了添加代码和缓慢执行之外,它不做任何有用的事情。所以,如果你要重写,你应该在 中做一些事情,否则你应该完全删除。.catch().catch().catch()

该一般结构的通常要点是,当您想要执行某些内容(例如记录错误或清理某些状态(例如关闭文件)时,但您希望承诺链继续为被拒绝。.catch()

promise.then(function(result){
    //some code
}).catch(function(error) {
    // log and rethrow 
    console.log(error);
    throw error;
});

在教程中,它可能只是为了向人们展示他们可以在哪里捕获错误,或者教授处理错误的概念,然后重新抛出它。


捕获和重新抛出的一些有用原因如下:

  1. 您希望记录错误,但将承诺链保留为已拒绝。
  2. 您希望将错误转换为其他错误(通常是为了在链的末端更轻松地处理错误)。在这种情况下,您将重新抛出其他错误。
  3. 您希望在承诺链继续之前执行一堆处理(例如关闭/可用资源),但您希望承诺链保持拒绝状态。
  4. 如果出现故障,您希望在承诺链中的此时放置调试器的断点
  5. 您希望处理一个特定的错误或一组错误,但要重新抛出其他错误,以便它们传播回调用方。

但是,在 catch 处理程序中没有其他代码的情况下,对同一错误的普通捕获和重写不会对代码的正常运行执行任何有用的操作。


答案 2

和 方法都返回 Promises,如果在任一处理程序中引发异常,则返回的 promise 将被拒绝,异常将被捕获到下一个拒绝处理程序中。.then().catch()

在下面的代码中,我们在第一个中抛出一个异常,该异常在第二个中捕获:.catch().catch()

new Promise((resolve, reject) => {
    console.log('Initial');

    resolve();
})
.then(() => {
    throw new Error('Something failed');
        
    console.log('Do this'); // Never reached
})
.catch(() => {
    console.log('Something failed');
    throw new Error('Something failed again');
})
.catch((error) => {
    console.log('Final error : ', error.message);
});

第二个返回一个已实现的承诺,可以调用处理程序:.catch().then()

new Promise((resolve, reject) => {
    console.log('Initial');

    resolve();
})
.then(() => {
    throw new Error('Something failed');
        
    console.log('Do this'); // Never reached
})
.catch(() => {
    console.log('Something failed');
    throw new Error('Something failed again');
})
.catch((error) => {
    console.log('Final error : ', error.message);
})
.then(() => {
    console.log('Show this message whatever happened before');
});

有用的参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch

希望这有帮助!