尝试/ catch异步/等待块

我正在挖掘节点7异步/等待功能,并像这样在代码中徘徊

async function main() {
  try {
    var quote = await getQuote();
    console.log(quote);
  } catch(error) {
    console.error(error);
  }
}

这似乎是解决/拒绝或返回/抛出异步/等待的唯一可能性,但是,v8不会优化try / catch块内的代码?!

有替代品吗?


备择方案

另一种方法是:

async function main() {
  try {
    var quote = await getQuote();
    console.log(quote);
  } catch (error) {
    console.error(error);
  }
}

会是这样的,明确使用承诺:

function main() {
  getQuote().then((quote) => {
    console.log(quote);
  }).catch((error) => {
    console.error(error);
  });
}

或类似的东西,使用延续传球风格:

function main() {
  getQuote((error, quote) => {
    if (error) {
      console.error(error);
    } else {
      console.log(quote);
    }
  });
}

原始示例

您的原始代码所做的是暂停执行并等待getQuote()返回的许诺来解决。 然后它继续执行,并将返回的值写入var quote ,然后在解析promise时将其打印出来,或者抛出异常并运行catch块以在承诺被拒绝时打印错误。

您可以使用Promise API直接执行相同的操作,就像第二个示例中那样。

性能

现在,为了表演。 让我们来测试它!

我只写了这段代码 - f1()给出1作为返回值, f2()作为异常抛出1

function f1() {
  return 1;
}

function f2() {
  throw 1;
}

现在让我们先用f1()调用相同的代码百万次:

var sum = 0;
for (var i = 0; i < 1e6; i++) {
  try {
    sum += f1();
  } catch (e) {
    sum += e;
  }
}
console.log(sum);

然后让我们将f1()更改为f2()

var sum = 0;
for (var i = 0; i < 1e6; i++) {
  try {
    sum += f2();
  } catch (e) {
    sum += e;
  }
}
console.log(sum);

这是我为f1得到的结果:

$ time node throw-test.js 
1000000

real    0m0.073s
user    0m0.070s
sys     0m0.004s

这是我得到的f2

$ time node throw-test.js 
1000000

real    0m0.632s
user    0m0.629s
sys     0m0.004s

看起来你可以在一个单线程的过程中做一些事情,例如200万秒。 如果你做的不止这些,那么你可能需要担心它。

概要

我不会担心Node中的情况。 如果这样的事情被大量使用,那么V8或SpiderMonkey或Chakra团队最终会对其进行优化,并且每个人都会遵循 - 它不像原则那样优化,这不是问题。

即使它没有被优化,我仍然会争辩说,如果你在Node中最大化你的CPU,那么你应该编写你的C语言编码 - 这就是本地插件的用途,等等。 或者也许像Node.native这样的东西比Node.js更适合工作。

我想知道什么是需要抛出这么多异常的用例。 通常抛出一个异常而不是返回一个值就是一个例外。


替代类似于Golang中的错误处理

因为异步/等待使用承诺之下的承诺,你可以写一个像这样的小实用程序功能:

export function catchEm(promise) {
  return promise.then(data => [null, data])
    .catch(err => [err]);
}

然后在需要捕获一些错误时将其导入,然后包装异步函数,该函数返回一个承诺。

import catchEm from 'utility';

async performAsyncWork() {
  const [err, data] = await catchEm(asyncFunction(arg1, arg2));
  if (err) {
    // handle errors
  } else {
    // use data
  }
}

async function main() {
  var getQuoteError
  var quote = await getQuote().catch(err => { getQuoteError = err }

  if (getQuoteError) return console.error(err)

  console.log(quote)
}

或者,不要声明可能的var在顶部可以保存错误

if (quote instanceOf Error) ...

尽管如果类似的错误或引用错误被抛出,那将无法工作。 虽然可以确保它是一个常规错误

async function main() {
  var quote = await getQuote().catch(err => {
    console.error(err)      

    return new Error('Error getting quote')
  })

  if (quote instanceOf Error) return quote // get out of here or do whatever

  console.log(quote)
}

我最喜欢的是将所有东西都包装在一个大的try-catch块中,在这个块中创建了多个promise,这可能会使创建它的承诺特别处理错误变得非常麻烦。 与替代多个try-catch块,我觉得同样繁琐

链接地址: http://www.djcxy.com/p/55387.html

上一篇: try/catch blocks with async/await

下一篇: Async wait for a function