选择
另一种说法是:
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,如果承诺已解决,则打印该值;如果承诺被拒绝,则抛出异常并运行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来编写你的数字运算——这就是本地插件的用途。或者像节点这样的东西。native会比Node.js更适合这项工作。
我想知道什么用例需要抛出这么多异常。通常抛出一个异常而不是返回一个值,嗯,是一个异常。