我听到这样的意见,你应该避免使用try / catch,因为它需要很多资源。那么可以承诺错误处理可能会更快吗?或者根本没关系?
function f(somethingDangerous) {
return new Promise((resolve, reject) => {
// try {
// somethingDangerous();
// resolve();
// } catch (err) {
// reject(err);
// }
// VS
somethingDangerous();
resolve();
}).catch((err) => {
console.error('Catched: ' + err);
});
}
f(() => {throw 'DANGEROUS THING';});
UPD :我知道try / catch不会在内部使用异步代码。我只是想知道是否有任何理由因为性能问题而避免尝试/捕获?以上两种方法之间有什么区别吗?
UPD2 :试图让我的马匹赛跑:) https://jsperf.com/try-catch-vs-promise
答案 0 :(得分:11)
您应该将Promises 仅用于异步函数,而不是其他任何内容。不要滥用它们作为错误monad,这将浪费资源,它们固有的异步会使一切变得更加繁琐。
如果您有同步代码,请使用try
/ catch
进行异常处理。
/* Wrong */
return new Promise(function(resolve, reject) {
resolve(x / y);
}).catch(err => NaN)
/* Right */
try {
return x / y;
} catch(e) {
return NaN;
}
Iff 您已经拥有承诺代码,在某些情况下可以避免这种情况:当您希望异常拒绝承诺时。在这些情况下,你应该让你的承诺的内置错误处理完成它的工作,而不是通过一个额外但毫无意义的try
/ catch
层来复杂化所有内容:
/* Wrong */
new Promise(function(resolve, reject) {
try { // when used synchronous in the executor callback
…
resolve(somethingSynchronous());
} catch (e) {
reject(e);
}
});
/* Right */
new Promise(function(resolve, reject) {
…
resolve(somethingExceptionally());
});
/* Wrong */
….then(function(res) {
try {
…
return somethingExceptionally();
} catch(e) {
return Promise.reject(e);
}
}).…
/* Right */
….then(function(res) {
…
return somethingExceptionally();
}).…
答案 1 :(得分:2)
try/catch
代码时, synchronous
成语很有效,但是asynchronous
操作会使它无用,不会捕获任何错误。即,当外部堆栈通过并且到达最后一行而没有任何错误时,该函数将开始其过程。如果异步函数中将来某个时候发生错误 - 什么都不会被捕获。
当我们使用Promise
时,“我们已经失去了错误处理”,您可能会说。这是正确的,我们不需要在这里做任何特殊的事情来传播错误,因为我们返回一个promise并且内置了对错误流的支持。
答案 2 :(得分:-2)
基于此基准测试,我发现大多数应用程序的性能都不会受到此类决策的影响。
https://jsperf.com/try-catch-vs-promise
注意:至少在使用" async / await"时,try / catch确实可以使用异步代码!