使用 async/await 尝试/捕获块 [英] try/catch blocks with async/await

查看:25
本文介绍了使用 async/await 尝试/捕获块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

function getQuote() {let quote = "Lorem ipsum dolor sat amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut Labore et dolore magna aliqua.";返回报价;}异步函数 main() {尝试 {var quote = await getQuote();控制台日志(引用);} 捕捉(错误){控制台错误(错误);}}main();

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

有替代品吗?

解决方案

替代方案

另一种选择:

异步函数 main() {尝试 {var quote = await getQuote();控制台日志(引用);} 捕捉(错误){控制台错误(错误);}}

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

function main() {getQuote().then((quote) => {控制台日志(引用);}).catch((错误) => {控制台错误(错误);});}

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

function main() {getQuote((错误,报价) => {如果(错误){控制台错误(错误);} 别的 {控制台日志(引用);}});}

原始示例

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

您可以像在第二个示例中一样直接使用 Promise API 执行相同的操作.

性能

现在,为了表演.让我们来测试一下!

我刚刚写了这段代码 - f1() 给出 1 作为返回值,f2() 抛出 1作为例外:

function f1() {返回 1;}函数 f2() {扔1;}

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

var sum = 0;for (var i = 0; i <1e6; i++) {尝试 {总和 += f1();}赶上(e){总和 += e;}}控制台日志(总和);

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

var sum = 0;for (var i = 0; i <1e6; i++) {尝试 {总和 += f2();}赶上(e){总和 += e;}}控制台日志(总和);

这是我为 f1 得到的结果:

$ 时间节点 throw-test.js1000000真实 0m0.073s用户 0m0.070s系统 0m0.004s

这是我为 f2 得到的:

$ 时间节点 throw-test.js1000000真实 0m0.632s用户 0m0.629s系统 0m0.004s

似乎您可以在一个单线程进程中每秒执行 200 万次抛出之类的事情.如果你做的不止这些,那么你可能需要担心它.

总结

我不会担心 Node.js 中的类似问题.如果这样的东西被大量使用,那么它最终会被 V8 或 SpiderMonkey 或 Chakra 团队优化,每个人都会效仿——这并不是说它没有作为原则优化,这不是问题.

即使它没有优化,我仍然认为如果你在 Node 中最大化你的 CPU,那么你可能应该用 C 编写你的数字运算 - 这就是本机插件的用途等等.或者,node.native 之类的东西可能比 Node.js 更适合这项工作.>

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

I'm digging into the node 7 async/await feature and keep stumbling across code like this

function getQuote() {
  let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
  return quote;
}

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

main();

This seems to be the only possibility resolve/reject or return/throw with async/await, however, v8 doesn't optimise code within try/catch blocks?!

Are there alternatives?

解决方案

Alternatives

An alternative to this:

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

would be something like this, using promises explicitly:

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

or something like this, using continuation passing style:

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

Original example

What your original code does is suspend the execution and wait for the promise returned by getQuote() to settle. It then continues the execution and writes the returned value to var quote and then prints it if the promise was resolved, or throws an exception and runs the catch block that prints the error if the promise was rejected.

You can do the same thing using the Promise API directly like in the second example.

Performance

Now, for the performance. Let's test it!

I just wrote this code - f1() gives 1 as a return value, f2() throws 1 as an exception:

function f1() {
  return 1;
}

function f2() {
  throw 1;
}

Now let's call the same code million times, first with f1():

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

And then let's change f1() to f2():

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

This is the result I got for f1:

$ time node throw-test.js 
1000000

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

This is what I got for f2:

$ time node throw-test.js 
1000000

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

It seems that you can do something like 2 million throws a second in one single-threaded process. If you're doing more than that then you may need to worry about it.

Summary

I wouldn't worry about things like that in Node. If things like that get used a lot then it will get optimized eventually by the V8 or SpiderMonkey or Chakra teams and everyone will follow - it's not like it's not optimized as a principle, it's just not a problem.

Even if it isn't optimized then I'd still argue that if you're maxing out your CPU in Node then you should probably write your number crunching in C - that's what the native addons are for, among other things. Or maybe things like node.native would be better suited for the job than Node.js.

I'm wondering what would be a use case that needs throwing so many exceptions. Usually throwing an exception instead of returning a value is, well, an exception.

这篇关于使用 async/await 尝试/捕获块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆