迹忆客 专注技术分享

当前位置:主页 > 学无止境 >

异步堆栈跟踪:为什么 await 击败了 Promise#then()

作者:迹忆客 最近更新:2023/01/09 浏览次数:

与直接使用 promises 相比,asyncawait 不仅可以使开发人员的代码更具可读性——它们还可以在 JavaScript 引擎中实现一些有趣的优化! 这篇文章是关于这样一种优化,涉及异步代码的堆栈跟踪。

awaitvanilla promises 的根本区别在于 await X() 暂停当前函数的执行,而 promise.then(X) 在将 X 调用添加到回调链后继续执行当前函数。 在堆栈跟踪的上下文中,这种差异非常显着。

promise 链在任何时候抛出未处理的异常时,JavaScript 引擎会显示错误消息和(希望如此)有用的堆栈跟踪。 作为一名开发人员,无论我们使用普通的 promise 还是 asyncawait,我们都期望这一点。关于 promise 也可以参考我们之前的如何创建自己的 Promise这篇文章。

Vanilla promise

想象一个场景,当对异步函数 b 的调用解析时调用函数 c

const a = () => {
    b().then(() => c());
};

调用 a 时,会同步发生以下情况:

  • b 被调用并返回一个 promise ,该 promise 将在未来某个时候解决。
  • .then 回调(实际上是调用 c())被添加到回调链中(或者,用 V8 术语来说:[...] 被添加为解析处理程序)。

之后,我们就完成了函数 a 中的代码的执行。 a 永远不会挂起,并且在对 b 的异步调用解决时上下文已经消失。 想象一下如果 b(或 c)异步抛出异常会发生什么。 堆栈跟踪应该包括 a,因为那是调用 b(或 c)的地方,对吗? 既然我们不再提及 a ,那怎么可能呢?

为了让它工作,JavaScript 引擎需要在上述步骤之外做一些事情:它在它仍有机会的时间内捕获并存储堆栈跟踪。 在 V8 中,堆栈跟踪附加到 b 返回的 promise 。 当 promise 执行时,堆栈跟踪将被传递,以便 c 可以根据需要使用它。

捕获堆栈跟踪需要时间(即降低性能); 存储这些堆栈跟踪需要内存。

async/await

这是同一个程序,使用 async/await 而不是 vanilla promises 编写:

const a = async () => {
    await b();
    c();
};

使用 await,即使我们没有在 await 调用时收集堆栈跟踪,我们也可以恢复调用链。 这是可能的,因为 a 被挂起,等待 b 解析。 如果 b 抛出异常,则可以通过这种方式按需重建堆栈跟踪。 如果 c 抛出异常,则可以像同步函数一样构建堆栈跟踪,因为我们仍在发生这种情况的时候。

建议

与大多数看似“只是语法糖”的 ECMAScript 功能一样,async/await 不止于此。

遵循以下建议,使 JavaScript 引擎能够以更高效和内存效率更高的方式处理堆栈跟踪:

  • vanilla promises 更喜欢 async/await
  • 使用 @babel/preset-env 避免不必要地转译 async/await

尽管 V8 尚未实现此优化,但遵循此建议可确保我们(或其他 JavaScript 引擎)实现后的最佳性能。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

C# 中的 async 和 await

发布时间:2024/02/03 浏览次数:116 分类:编程语言

async 和 await 关键字用于 C# 中的异步编程。C# 中的异步编程 如果同步应用程序中有任何进程被阻止,则整个应用程序将被阻止并停止响应

Python 中的 Promise 系列

发布时间:2023/06/19 浏览次数:367 分类:Python

本篇文章将介绍如何用 Python 编写一系列 promise。 首先,我们将讨论 Python 中的异步编程。接下来,我们将讨论 Python 中的回调函数。

在 Python Lambda 中使用 Await

发布时间:2023/06/13 浏览次数:165 分类:Python

在 Python 中,要实现异步编程,我们可以将 async/await 特性与函数一起使用,但我们使用 lambda 函数来实现。 本文将讨论在 Python lambda 函数中使用 await 的可能性。Python Lamda 中没有async/await lambda

在 TypeScript 中返回一个 Promise

发布时间:2023/03/19 浏览次数:586 分类:TypeScript

本教程讨论如何在 TypeScript 中返回正确的 Promise。这将提供 TypeScript 中 Returns Promise 的完整编码示例,并完整演示每个步骤。

深度理解 ES6 Promise

发布时间:2023/03/07 浏览次数:159 分类:WEB前端

现在我们开始 ES6 深度系列。 如果大家以前从未来到过这里,请从 ES6 教程 开始。 这篇是关于 ES6 中的 Promise API。 如果觉得该动画非常复杂,请继续阅读! Promises 是一个非常复杂的范

JavaScript 中检查函数是否返回的 Promise

发布时间:2022/12/15 浏览次数:847 分类:JavaScript

要检查函数是否返回 Promise ,请检查函数是否异步或调用它并检查函数是否返回具有函数类型 then 属性的对象。 如果满足任一条件,该函数将返回一个 Promise 。 // ✅ Promise check functio

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便