我们应该selectasynchronous在Javascript中使用Promise来等待

我知道async await是镇上的新Promise ,这是一种编写asynchronous代码的新方法,我也知道

我们不必写,然后创build一个匿名函数来处理响应

Async/await使得最终可以同时处理同步错误和asynchronous错误

promise链返回的错误堆栈不知道发生错误的位置。 但是,来自async / await的错误堆栈指向包含该错误的函数

等等…

但在这里我做了一个简单的基准标记https://repl.it/repls/FormalAbandonedChimpanzee

在基准testing中,我已经运行了2百万次。 在第一个循环中,我正在调用另一个函数返回1的函数,我正在调用一个函数,抛出1作为例外。

正在调用正在返回1的函数的第一个循环占用的时间差不多是抛出1的函数的一半。

这表明, throw所花的时间几乎是return所花时间的两倍

 node v7.4 linux/amd64 return takes 1.233seconds 1000000 throw takes 2.128seconds 1000000 

基准代码如下

 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); 

您的基准与async/await与原始承诺之间的性能无关。 我所能看到的是,抛出一个错误需要更长的时间来计算。 这是预料之中的。

回到主要问题,应该使用async/await而不是与原始承诺?

请记住, async/await仅仅是对原始承诺的语法糖,所以不应该对整体性能产生太大的影响。 但是,它确实使您的代码更加线性化,从而消除了开发人员的大量认知开销。

结论是使用你喜欢的。 承诺可以是polyfill'd,但新的语法不能,因此,在决定使用哪种样式时,可能需要记住这一点。


一些误解:

从承诺链返回的错误堆栈不知道发生错误的位置

那是不正确的。 快速检查:

 function error() { return new Promise(function(res, rej) { res(undefined()); // uh oh }); } error().then(console.log, e => console.log("Uh oh!", e.stack)); 

大多数情况下,答案是“这取决于”。

在谈论性能之前,更重要的方面是代码的可维护性,以及async / await vs原始Promise限制。

async / await是按顺序执行asynchronous代码的好方法,而Promise允许您同时运行asynchronous代码。

 async function foo() { const a = await backend.doSomething() const b = await backend.doAnotherThing() return a + b } 

在上面的代码中, backend.doAnotherThing()将不会被执行,直到backend.doSomething()返回。 另一方面:

 function foo() { Promise.all([backend.doSomething(), backend.doAnotherThing()]) .then(([a, b]) => { return a + b }) } 

将执行两个呼叫,并等待两个完成。

正如你所提到的async / await的好处,我个人使用它广泛。 除上述情况外。

如果你需要性能,对你来说, async / await vs Promise之间的性能差异比Promiseasync / await的可读性好处更重要。

只要是有意识的select,你应该没问题。