替代方案
这是一个替代方案:
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}
使用显式的 Promises ,可能会像这样:
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()
返回的Promise解决。然后它继续执行并将返回的值写入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
看起来你可以在一个单线程的进程中做到每秒2百万次的操作。如果你需要做更多的话,那就要担心一下了。
概述
在Node中,我不会为这样的事情担心。如果这类问题经常被使用,那么V8、SpiderMonkey或Chakra团队最终会对其进行优化,并且大家都会跟进 - 这不是原则上没有优化,而是不是一个问题。
即使它没有被优化,我仍然认为,如果你在Node中占用了CPU的最大值,那么你可能应该用C语言编写你的数值计算 - 这就是本地插件的作用之一。或者也许像node.native这样的东西比Node.js更适合这项工作。
我想知道需要抛出这么多异常的用例是什么。通常,抛出异常而不是返回一个值,是一种特殊情况。
async
/await
处理拒绝的语法。 - Bergi