Vik*_*sal 10 javascript asynchronous v8 node.js async-await
我知道这async await
是Promise
镇上的新东西,它是编写异步代码的新方法,我也知道
我们没有写.then
,创建一个匿名函数来处理响应
Async/await
最终可以使用相同的构造,旧的try/catch来处理同步和异步错误
从promise
链返回的错误堆栈没有提供错误发生位置的线索.但是,async/await中的错误堆栈指向包含错误的函数
等等...
但在这里我做了一个简单的基准测试https://repl.it/repls/FormalAbandonedChimpanzee
在基准测试中,我已经运行了2次循环100万次.在第一个循环中,我调用的函数在另一个函数中返回1我正在调用一个函数,它抛出1作为异常.
调用返回1的函数的第一个循环所花费的时间几乎是将1作为错误抛出的函数的一半.
这表明所花费的时间throw
几乎是所用时间的两倍return
node v7.4 linux/amd64
return takes 1.233seconds
1000000
throw takes 2.128seconds
1000000
Run Code Online (Sandbox Code Playgroud)
以下基准代码
function f1() {
return 1;
}
function f2() {
throw 1;
}
function parseHrtimeToSeconds(hrtime) {
var seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
return seconds;
}
var sum = 0;
var start = 0;
var i = 0;
start = process.hrtime();
for (i = 0; i < 1e6; i++) {
try {
sum += f1();
} catch (e) {
sum += e;
}
}
var seconds = parseHrtimeToSeconds(process.hrtime(start));
console.log('return takes ' + seconds + 'seconds');
console.log(sum);
sum = 0;
start = process.hrtime();
for (i = 0; i < 1e6; i++) {
try {
sum += f2();
} catch (e) {
sum += e;
}
}
seconds = parseHrtimeToSeconds(process.hrtime(start));
console.log('throw takes ' + seconds + 'seconds');
console.log(sum);
Run Code Online (Sandbox Code Playgroud)
Der*_*會功夫 12
您的基准与async/await
vs raw promises 之间的性能无关.我只能看到抛出一个错误需要更长的时间来计算.这是预料之中的.
回到主要问题,应该使用async/await
而不是.then
原始的承诺?
请记住,async/await
仅仅是原始承诺的语法糖,所以不应该对整体表现产生太大影响.但是,它确实使您的代码更加线性,从而消除了开发人员的大量认知开销.
结论是使用你喜欢的.Promise可以被polyfill'd但新的语法不能,所以你可能想在决定使用哪种样式时记住这一点.
一些误解:
从promise链返回的错误堆栈没有提供错误发生位置的线索
事实并非如此.快速检查:
function error() {
return new Promise(function(res, rej) {
res(undefined()); // uh oh
});
}
error().then(console.log, e => console.log("Uh oh!", e.stack));
Run Code Online (Sandbox Code Playgroud)
显示整个错误堆栈,包括位置.
大多数情况下,答案是"它取决于".
在谈论性能之前,更重要的方面是代码的可维护性和async
/ await
vs raw的限制Promise
.
async
/ await
是顺序执行异步代码的好方法,同时Promise
使您能够同时运行异步代码.
async function foo() {
const a = await backend.doSomething()
const b = await backend.doAnotherThing()
return a + b
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,在返回backend.doAnotherThing()
之前不会执行backend.doSomething()
.另一方面:
function foo() {
Promise.all([backend.doSomething(), backend.doAnotherThing()])
.then(([a, b]) => {
return a + b
})
}
Run Code Online (Sandbox Code Playgroud)
将执行两个调用,并等待两个调用完成.
正如您提到的async
/ 的好处await
,我个人广泛使用它.除上述情况外.
如果你需要性能和你,那么async
/ await
vs 之间的性能差异Promise
比async
/ await
over 的可读性好处更重要Promise
,所有意味着继续.
只要是有意识的选择,你应该没事.
更新:如Derek朕会功夫所述
您可以使用async
/ await
by 获得并行执行:
async function foo() {
const p1 = backend.doSomething()
const p2 = backend.doAnotherThing()
return await p1 + await p2
}
Run Code Online (Sandbox Code Playgroud)