什么是更快:尝试捕捉与承诺

时间:2017-03-07 12:58:02

标签: javascript node.js promise try-catch es6-promise

我听到这样的意见,你应该避免使用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

3 个答案:

答案 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确实可以使用异步代码!