小编典典

使用 async/await 尝试/捕获块

all

我正在深入研究 node 7 async/await 功能,并不断遇到这样的代码

function getQuote() {
  let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit laborum.";
  return quote;
}

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

main();

这似乎是使用 async/await 解决/拒绝或返回/抛出的唯一可能性,但是,v8 没有优化 try/catch 块中的代码?!

有替代品吗?


阅读 113

收藏
2022-07-04

共1个答案

小编典典

备择方案

对此的替代方法:

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
被解决时打印它,或者如果 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.js 中的类似事情。如果这样的东西被大量使用,那么它最终会被 V8 或 SpiderMonkey 或 Chakra
团队优化,每个人都会效仿——这并不是作为原则没有优化,只是没有问题。

即使它没有经过优化,我仍然会争辩说,如果你在 Node 中最大化你的 CPU,那么你可能应该用 C
编写你的数字运算——这就是本机插件的用途,等等。或者也许像node.native这样的东西会比
Node.js 更适合这项工作。

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

2022-07-04