3 回答
TA贡献1785条经验 获得超8个赞
备择方案
替代方法:
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语言编写数字运算法则-这就是本机插件的用途。或者也许像node.native这样的事情比Node.js更适合这份工作。
我想知道什么是用例,需要抛出这么多异常。通常,抛出异常而不是返回值是一个异常。
TA贡献1802条经验 获得超5个赞
async function main() {
var getQuoteError
var quote = await getQuote().catch(err => { getQuoteError = err }
if (getQuoteError) return console.error(err)
console.log(quote)
}
另外,您也可以声明一个变量而不是在顶部声明错误,而不是声明
if (quote instanceof Error) {
// ...
}
虽然如果抛出TypeError或Reference错误之类的东西,那将不起作用。您可以通过以下方式确保它是常规错误
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,这使得处理错误(特别是针对创建它的promise)变得很麻烦。另一种选择是多个try-catch块,我觉得同样麻烦
TA贡献1998条经验 获得超6个赞
与Golang中的错误处理类似的替代方法
因为async / await在幕后使用promises,所以您可以编写一个小的实用程序函数,如下所示:
export function catchEm(promise) {
return promise.then(data => [null, data])
.catch(err => [err]);
}
然后,在需要捕获一些错误时将其导入,并包装异步函数,该函数将返回一个Promise。
import catchEm from 'utility';
async performAsyncWork() {
const [err, data] = await catchEm(asyncFunction(arg1, arg2));
if (err) {
// handle errors
} else {
// use data
}
}
- 3 回答
- 0 关注
- 584 浏览
添加回答
举报