尝试/ catch异步/等待块
我正在挖掘节点7异步/等待功能,并像这样在代码中徘徊
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch(error) {
console.error(error);
}
}
这似乎是解决/拒绝或返回/抛出异步/等待的唯一可能性,但是,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时将其打印出来,或者抛出异常并运行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更适合工作。
我想知道什么是需要抛出这么多异常的用例。 通常抛出一个异常而不是返回一个值就是一个例外。
替代类似于Golang中的错误处理
因为异步/等待使用承诺之下的承诺,你可以写一个像这样的小实用程序功能:
export function catchEm(promise) {
return promise.then(data => [null, data])
.catch(err => [err]);
}
然后在需要捕获一些错误时将其导入,然后包装异步函数,该函数返回一个承诺。
import catchEm from 'utility';
async performAsyncWork() {
const [err, data] = await catchEm(asyncFunction(arg1, arg2));
if (err) {
// handle errors
} else {
// use data
}
}
async function main() {
var getQuoteError
var quote = await getQuote().catch(err => { getQuoteError = err }
if (getQuoteError) return console.error(err)
console.log(quote)
}
或者,不要声明可能的var在顶部可以保存错误
if (quote instanceOf Error) ...
尽管如果类似的错误或引用错误被抛出,那将无法工作。 虽然可以确保它是一个常规错误
async function main() {
var quote = await getQuote().catch(err => {
console.error(err)
return new Error('Error getting quote')
})
if (quote instanceOf Error) return quote // get out of here or do whatever
console.log(quote)
}
我最喜欢的是将所有东西都包装在一个大的try-catch块中,在这个块中创建了多个promise,这可能会使创建它的承诺特别处理错误变得非常麻烦。 与替代多个try-catch块,我觉得同样繁琐
链接地址: http://www.djcxy.com/p/55387.html