我正在深入研究 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 块中的代码?!
有替代品吗?
对此的替代方法:
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 块。
getQuote()
var quote
你可以直接使用 Promise API 来做同样的事情,就像第二个例子一样。
现在,为了表演。让我们测试一下!
我刚刚写了这段代码 -作为返回值f1()给出,作为异常抛出:1``f2()``1
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():
f2()
var sum = 0; for (var i = 0; i < 1e6; i++) { try { sum += f2(); } catch (e) { sum += e; } } console.log(sum);
这是我得到的结果f1:
f1
$ time node throw-test.js 1000000 real 0m0.073s user 0m0.070s sys 0m0.004s
这就是我得到的f2:
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 更适合这项工作。
我想知道什么是需要抛出这么多异常的用例。通常抛出异常而不是返回值就是异常。