Javascript 在承诺捕获中重新抛出错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42167274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rethrowing error in promise catch
提问by Tyler Durden
I found the following code in a tutorial:
我在教程中找到了以下代码:
promise.then(function(result){
//some code
}).catch(function(error) {
throw(error);
});
I'm a bit confused: does the catch call accomplish anything? It seems to me that it doesn't have any effect, since it simply throws the same error that was caught. I base this on how a regular try/catch works.
我有点困惑:catch 调用有什么作用吗?在我看来它没有任何效果,因为它只是抛出与捕获到的相同的错误。我基于常规 try/catch 的工作原理。
回答by jfriend00
There is no point to a naked catch and throw as you show. It does not do anything useful except add code and slow execution. So, if you're going to .catch()and rethrow, there should be something you want to do in the .catch(), otherwise you should just remove the .catch()entirely.
正如你所展示的那样,赤裸裸的接球和投球是没有意义的。除了添加代码和缓慢执行之外,它没有做任何有用的事情。所以,如果你要.catch()重新抛出,应该有你想要在 中做的事情.catch(),否则你应该完全删除.catch()。
The usual point for that general structure is when you want to execute something in the .catch()such as log the error or clean up some state (like close files), but you want the promise chain to continue as rejected.
该通用结构的通常点是当您想要在.catch()诸如记录错误或清理某些状态(如关闭文件)中执行某些操作时,但您希望承诺链继续被拒绝。
promise.then(function(result){
//some code
}).catch(function(error) {
// log and rethrow
console.log(error);
throw error;
});
In a tutorial, it may be there just to show people where they can catch errors or to teach the concept of handling the error, then rethrowing it.
在教程中,它可能只是向人们展示他们可以在哪里捕获错误或教导处理错误的概念,然后重新抛出它。
Some of the useful reasons for catching and rethrowing are as follows:
捕获和重新抛出的一些有用原因如下:
- You want to log the error, but keep the promise chain as rejected.
- You want to turn the error into some other error(often for easier error processing at the end of the chain). In this case, you would rethrow a different error.
- You want to do a bunch of processing before the promise chain continues(such as close/free resources) but you want the promise chain to stay rejected.
- You want a spot to place a breakpoint for the debuggerat this point in the promise chain if there's a failure.
- 你想记录错误,但保持承诺链被拒绝。
- 您想将错误转换为其他错误(通常是为了在链的末尾更容易处理错误)。在这种情况下,您将重新抛出一个不同的错误。
- 您希望在承诺链继续之前进行一系列处理(例如关闭/释放资源),但您希望承诺链保持被拒绝。
- 如果出现故障,您希望在承诺链中的这一点为调试器放置一个断点。
But, a plain catch and rethrow of the same error with no other code in the catch handler doesn't do anything useful for normal running of the code.
但是,在 catch 处理程序中没有其他代码的情况下,简单地捕获和重新抛出相同的错误对代码的正常运行没有任何用处。
回答by Philippe Sultan
Both .then()and .catch()methods return Promises, and if you throw an Exception in either handler, the returned promise is rejected and the Exception will be caught in the next reject handler.
无论.then()和.catch()方法返回承诺,如果在任一处理程序抛出异常,返回的承诺被拒绝,异常会被夹在接下来的拒绝处理。
In the following code, we throw an exception in the first .catch(), which is caught in the second .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);
});
The second .catch()returns a Promised that is fulfilled, the .then()handler can be called :
第二个.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');
});
Useful reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch
有用的参考:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch
Hope this helps!
希望这可以帮助!
回答by Matt Fernandez
So it sounds like your question is, "In the promise chain, what does the .catch()method do?"
所以听起来你的问题是,“在承诺链中,该.catch()方法有什么作用?”
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
The throw statement "will stop (the statements after throw won't be executed), and control will be passed to the first catch block in the call stack. If no catch block exists among caller functions, the program will terminate."
throw 语句“将停止(throw 之后的语句不会被执行),并且控制将被传递到调用堆栈中的第一个 catch 块。如果调用者函数之间不存在 catch 块,则程序将终止。”
In the promise chain, the .then()method will return some type of data chunk. This return of the chunk will complete the promise. The successful return of the data completes the promise. You can think of the .catch()method in the same way. .catch()however will handle unsuccessful data retrieves. The throw statement completes the promise. Occasionally, you will see developers use .catch((err) => {console.log(err))}which would also complete the promise chain.
在承诺链中,该.then()方法将返回某种类型的数据块。块的返回将完成承诺。数据的成功返回完成了承诺。你可以.catch()用同样的方式来思考这个方法。 .catch()但是会处理不成功的数据检索。throw 语句完成了承诺。有时,您会看到开发人员使用.catch((err) => {console.log(err))}这也将完成承诺链。
回答by trincot
There is no important difference if you leave out the catchmethod call completely.
如果catch完全省略方法调用,则没有重要区别。
The only thing it adds is an extra microtask, which in practice means you'll notice the rejection of the promise later than is the case for a promise that fails without the catchclause.
它唯一添加的是一个额外的微任务,这在实践中意味着你会比没有catch子句的承诺失败的情况更晚注意到承诺的拒绝。
The next snippet demonstrates this:
下一个片段演示了这一点:
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) );
Note how the second rejection is reported before the first. That is about the only difference.
请注意如何在第一次拒绝之前报告第二次拒绝。这是唯一的区别。

