Node版本8中异步/等待的性能指南

11

async/await 在nodejs的8版本中可用。这是nodejs中首次出现线性代码,这很好。更早的文章声称,在v8 JavaScript引擎中带有try/catch块的函数不会被优化。现在,async/await需要try/catch块来处理错误。因此,作为开发人员,如何保持相同的性能呢?


你尝试过使用.catch()了吗? - guest271314
@jfriend00,你指的是在 async/await 中使用 .catch() 的具体模式是什么?(async() => { "use strict"; await abc })() .then(result => console.log("resolved:", result)) .catch(err => console.error("rejected:", err)) - guest271314
@jfriend00 不,不要收集你所引用的具体模式。 - guest271314
1
@guest271314 - 请根据问题保持话题。如果在使用多个await语句的块中发生高级别拒绝,您必须使用try/catch来捕获它。如果您不理解,请阅读有关await和拒绝的内容。我不会在这里的评论中教育您。这类似于在promise链末尾使用.catch(),但是当使用多个await语句而不是promise链时,不能仅使用.catch()来捕获更高级别的拒绝。 - jfriend00
1
我认为你不需要使用try/catch,如果你像这样初始化:'userService.logIn(req, res) .then(result => res.json(result)) .catch(error => next(error));',每个拒绝/抛出的错误(如果没有在那里捕获)都将在这里处理。 - PVermeer
2个回答

13

try/catch 在 V8 5.3 (Node v7.x 及以上版本) 中的提交 9aac80f 中得到了 TurboFan 优化。这意味着历史上关于 try/catch 性能不佳的说法不再正确。
来自V8 博客帖子

过去,V8 在优化 ES2015+ 中发现的语言特性方面存在困难。例如,将异常处理(即 try/catch/finally)支持添加到 Crankshaft,即 V8 的经典优化编译器,从未变得可行。这意味着 V8 优化 ES6 特性(例如具有隐式 finally 子句的 for...of)的能力受到限制。Crankshaft 的限制以及将新语言特性添加到全代码生成器(V8 的基线编译器)中的整体复杂性,使得确保在 V8 中快速添加和优化新的 ES 特性变得困难。

幸运的是,Ignition 和 TurboFan(V8 的新解释器和编译器管道)从一开始就设计支持整个 JavaScript 语言,包括高级控制流、异常处理和最近的 ES2015 中的 for...of 和解构。Ignition 和 TurboFan 架构的紧密集成使得快速添加新功能并快速、逐步地优化它们成为可能。


async函数中使用try/catch只是Promise .then.catch方法的语法糖,因此性能取决于底层Promise实现。Bluebird 声称 具有比本地Promise实现更好的性能,因此理论上,如果Bluebird所声称的是真的,通过用Bluebird的Promise实现覆盖本地Promise实现,您将获得更好的try/catch性能。
例如,在Node中:const Promise = require("bluebird")global.Promise = require("bluebird")以全局方式覆盖它。

但请注意,这可能会在未来发生变化,因为原始Promise实现是使用JavaScript编写的,但最近已经重新实现为C++,可以在bug#5343中跟踪到。


1
接收TurboFan优化意味着什么? - jfriend00
@jfriend00 TurboFan是V8的优化编译器之一。在此处阅读更多信息:https://github.com/v8/v8/wiki/TurboFan - Svenskunganka
1
是的,我知道这是一种优化类型。问题是关于在Node.js版本8中使用async/awaittry/catch的性能问题,您并没有提供任何明确的信息。现在使用try/catchawait速度与以前相比有多快?或者与不使用async/await,只使用promise和.catch()编程相比如何?这才是真正回答问题的信息。 - jfriend00

3
我找到了一个Node.js v8中本地ES2015承诺和ES2017异步函数的性能比较。
回调、承诺和异步函数在 Node.js v8 中的性能表现,本机 Chrome V8 ES2015 承诺和 ES2017 异步函数的表现大约比 Bluebird 承诺慢 2 倍,使用的内存几乎是 Bluebird 的 2 倍。
并且 结论 Node.js v8 带来了显著提高的本机 ES2015 承诺和 ES2017 异步函数的性能,在引入本机 util.promisify 的同时进一步提高了性能。

Bluebird是Node.JS吗?我以为Chrome V8是Node的引擎。我有点困惑,请你能否澄清一下? - Pac0
2
@Pac0 BluebirdPromise 的用户实现。 - ponury-kostek
1
Bluebird包在原生Promise不可用时非常有用。但是他们的Promise实现并不完全符合规范。这就是为什么V8的实现略慢的原因。尽管实现已经大大改进,但与BlueBird几乎相当。我会使用原生Promise,因为它具有规范合规性,没有额外的依赖项,并且您将受益于未来的引擎优化。 - user835611
Bluebird几乎成为Node.js的事实标准。许多流行的库使用它而不是标准的promises,原因是其扩展和方便的功能集。Web通常带有糟糕的API。例如,考虑WebSocket。在初始化连接后分配回调、缺乏两阶段初始化、缺乏addEventListener()支持等。 - Brian Cannard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接