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

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

问题描述

我正在研究节点7的异步/等待功能,并不断绊倒这样的代码

 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(); 

这似乎是使用async/await进行解析/拒绝或返回/抛出的唯一可能性,但是,v8不会在try/catch块中优化代码吗?!

有其他选择吗?

解决方案

替代项

替代方法:

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

会这样,明确地使用promise:

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,然后在承诺被解决的情况下将其打印出来,或者抛出一个异常并运行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更适合该工作.

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

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.

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

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