承诺中的重新抛出错误

时间:2017-02-10 19:31:38

标签: javascript promise

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

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

我有点困惑:抓住电话会做什么吗?在我看来,它没有任何影响,因为它只是抛出了被捕获的相同错误。我的基础是常规的try / catch如何工作。

6 个答案:

答案 0 :(得分:71)

当你表现出来时,没有任何关于裸体捕捉和投掷的信息。除了添加代码和执行缓慢之外,它没有做任何有用的事情。所以,如果你要.catch()并重新抛出,那么你应该在.catch()中做一些事情,否则你应该完全删除.catch()

通用结构的通常要点是当你想在.catch()中执行某些操作时,例如记录错误或清理某些状态(如关闭文件),但是你希望promise链继续被拒绝

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

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

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

  1. 您希望记录错误,但保留承诺链为拒绝。
  2. 您希望将错误转换为其他错误(通常是为了在链的末尾更容易处理错误)。在这种情况下,您将重新抛出另一个错误。
  3. 您希望在承诺链继续之前进行一系列处理(例如关闭/免费资源),但您希望承诺链保持拒绝。
  4. 如果发生故障,您希望在声明链的此处为调试器设置断点
  5. 但是,在catch处理程序中没有其他代码的同一错误的普通捕获和重新抛出对正常运行代码没有任何帮助。

答案 1 :(得分:10)

.then().catch()方法都返回Promises,如果在任一处理程序中抛出异常,则拒绝返回的promise,并在下一个拒绝处理程序中捕获异常。

在下面的代码中,我们在第一个.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()返回一个已实现的Promised,可以调用.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

希望这有帮助!

答案 2 :(得分:4)

所以听起来你的问题是,“在承诺链中,.catch()方法做了什么?”

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw

throw语句“将停止(throw之后的语句不会被执行),并且控制将被传递给调用堆栈中的第一个catch块。如果调用函数之间不存在catch块,程序将终止。 “

在promise链中,.then()方法将返回某种类型的数据块。这个块的返回将完成承诺。数据的成功返回完成了承诺。您可以以相同的方式考虑.catch()方法。但是.catch()将处理不成功的数据检索。 throw语句完成了承诺。有时,您会看到开发人员使用.catch((err) => {console.log(err))}来完成承诺链。

答案 3 :(得分:3)

如果完全省略catch方法调用,则没有重要区别。

它唯一增加的是一个额外的微任务,实际上这意味着你会比没有catch子句的失败的情况更晚发现承诺的拒绝。

下一个代码段演示了这一点:



var p;
// Case 1: with catch
p = Promise.reject('my error 1')
       .catch(function(error) {
          throw(error);
       });

p.catch( error => console.log(error) );
// Case 2: without catch
p = Promise.reject('my error 2');

p.catch( error => console.log(error) );




注意在第一次拒绝之前如何报告第二次拒绝。这是唯一的区别。

答案 4 :(得分:0)

您实际上不需要将其扔掉,只需将Promise.catch保留为空,否则它将被视为取消处理拒绝,然后将代码包装在try catch中,它将自动捕获错误并向下传递

try{
  promise.then(function(result){
    //some code
  }).catch(function(error) {
    //no need for re throwing or any coding. but leave this as this otherwise it will consider as un handled
  });
}catch(e){
  console.log(e);
  //error can handle in here
}

答案 5 :(得分:0)

在promise链中,最好使用.catch

函数f2中的

ex: .then(...)。catch(e => reject(e));

  • test1-尝试捕获
  • test2-无需尝试或.catch
  • test3-带.catch

function f1() {
    return new Promise((resolve, reject) => {
        throw new Error('test');
    });
}

function f2() {
    return new Promise((resolve, reject) => {
        f1().then(value => {
            console.log('f1 ok ???');
        }).catch(e => reject(e));
    });
}

function test1() {
    console.log('test1 - with try catch - look in F12');
    try {
      f2().then(() => { // Uncaught (in promise) Error: test
        console.log('???'); });
    } catch (e) {
      console.log('this error dont catched');
    }
}

function test2() {
    console.log('test2 - without try or .catch - look in F12');
    f2(); // Uncaught (in promise) Error: test
}

function test3() {
  console.log('test3 - with .catch');
  f2().then(value => {
    console.log('??');
  }).catch(e => {
    console.log(' now its ok, error ', e);
  })
}

setTimeout(() => { test1(); 
  setTimeout(() => { test2(); 
    setTimeout(() => { test3(); 
    }, 100);
  }, 100);
}, 100);