备择方案
替代方案:
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 被解决,则打印它,或者抛出异常并运行 catch 块,如果 Promise 被拒绝,则打印错误。
您可以像第二个示例一样直接使用 Promise API 执行相同的操作。
表现
现在,为了表演。我们来测试一下吧!
我刚刚写了这段代码 -f1()
gives 1
作为返回值,f2()
throws 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()
to 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 万次抛出。如果你做的事情不止于此,那么你可能需要担心。
Summary
我不会担心 Node 中的类似问题。如果类似的东西被大量使用,那么它最终会被 V8 或 SpiderMonkey 或 Chakra 团队优化,每个人都会遵循 - 这并不是说它没有作为原则进行优化,这只是不是一个问题。
即使它没有优化,我仍然认为,如果你在 Node 中最大化了你的 CPU,那么你可能应该用 C 编写你的数字运算——这就是本机插件的用途。或者也许像这样的事情节点原生 https://github.com/d5/node.native比 Node.js 更适合这项工作。
我想知道需要抛出这么多异常的用例是什么。通常抛出异常而不是返回值就是异常。