使用 Chrome DevTools 调试异步 JavaScript 程序

发布于 2022-08-05 12:46:39 字数 8248 浏览 385 评论 0

使 JavaScript 独一无二的一个强大功能是它能够通过回调函数异步工作。 分配异步回调使您可以编写事件驱动的代码,但它也使跟踪错误成为一种令人毛骨悚然的体验,因为 JavaScript 不是以线性方式执行的。

幸运的是,现在在 Chrome DevTools 中,您可以查看异步 JavaScript 回调的 完整 调用堆栈!

异步调用堆栈的快速预告概述

异步调用堆栈的快速预告概述,我们很快就会分解这个演示的流程。

在 DevTools 中启用异步调用堆栈功能后,您将能够深入了解 Web 应用程序在不同时间点的状态。 遍历某些事件侦听器的完整堆栈跟踪, setInterval, setTimeout, XMLHttpRequest, promise, requestAnimationFrame, MutationObservers, 和更多。

当您遍历堆栈跟踪时,您还可以分析任何变量在该特定运行时执行点的值。 它就像您的手表表情的时间机器!

让我们启用此功能并看一下其中的一些场景。

在 Chrome 中启用异步调试

通过在 Chrome 中启用此新功能来试用它。 转到 Chrome Canary DevTools 的 Sources 面板的 调用堆栈 在右侧 切换复选框以打开或关闭异步调试。 (虽然一旦打开,您可能永远不想关闭它。)

打开或关闭异步功能

捕获延迟的计时器事件和 XHR 响应

您之前可能在 Gmail 中看到过:

Gmail 正在重试发送电子邮件

如果发送请求时出现问题(服务器出现问题或客户端存在网络连接问题),Gmail 会在短暂超时后自动尝试重新发送邮件。

为了了解异步调用堆栈如何帮助我们分析延迟的计时器事件和 XHR 响应,我使用 模拟 Gmail 示例 。 完整的 JavaScript 代码可以在上面的链接中找到,但流程如下:

模拟Gmail示例流程图

在上图中,以蓝色突出显示的方法是这个新的 DevTool 功能最有利的地方,因为这些方法是异步工作的。

通过只查看以前版本的 DevTools 中的调用堆栈面板, postOnFail()会给你很少的关于在哪里的信息 postOnFail()被调用。 但是看看开启异步堆栈时的区别:

在没有异步调用堆栈的模拟 Gmail 示例中设置断点

的调用堆栈面板 启用异步

在这里你可以看到 postOnFail()是从 AJAX 回调发起的,但没有更多信息。

在具有异步调用堆栈的模拟 Gmail 示例中设置断点

调用堆栈面板 启用异步

在这里您可以看到 XHR 是从 submitHandler()

打开异步调用堆栈后,您可以查看整个调用堆栈以轻松查看请求是否从 submitHandler()(在单击提交按钮后发生)或来自 retrySubmit()(这发生在之后 setTimeout() 延迟):

提交处理程序()

在具有异步调用堆栈的模拟 Gmail 示例中设置断点

重试提交()

在带有异步调用堆栈的模拟 Gmail 示例中设置的另一个断点

异步观察表达式

当您遍历完整的调用堆栈时,您监视的表达式也将更新以反映它当时所处的状态!

使用带有 aysnc 调用堆栈的监视表达式的示例

从过去的范围评估代码

除了简单地 DevTools JavaScript 控制台面板中与以前作用域中的代码进行交互。

想象一下,你是 Dr. Who,你需要一些帮助来比较你进入 Tardis 之前和“现在”的时钟。 从 DevTools 控制台,您可以轻松地评估、存储和计算来自不同执行点的值。

使用带有 aysnc 调用堆栈的 JavaScript 控制台的示例

将 JavaScript 控制台与异步调用堆栈结合使用来调试您的代码。 上面的演示可以在 这里

留在 DevTools 中操作表达式将节省您切换回源代码、进行编辑和刷新浏览器的时间。

解开链式承诺解决方案

如果您认为之前的模拟 Gmail 流程在不启用异步调用堆栈功能的情况下很难解开,您能想象使用更复杂的异步流程(如链式 Promise)会有多困难吗? 让我们重温一下 Jake Archibald 关于 JavaScript Promises

中遍历调用堆栈的小动画 async-best-example.html 示例

在没有异步调用堆栈的 Promise 示例中设置断点

的调用堆栈面板 启用异,请注意,在尝试调试 Promise 时,调用堆栈面板的信息非常短缺。

在带有异步调用堆栈的 Promise 示例中设置断点

调用堆栈面板 启用异步,这样的 Promise 很多回调。

深入了解您的网络动画

让我们更深入地了解 HTML5Rocks 档案。 还记得 Paul Lewis 用 requestAnimationFrame 实现的更精简、更简洁、更快的动画 吗?

打开 requestAnimationFrame demo ,在开头添加断点 update() post.html 的方法(大约第 874 行)。 借助异步调用堆栈,我们可以更深入地了解 requestAnimationFrame,包括一直走到发起滚动事件回调的能力。

在没有异步调用堆栈的 requestAnimationFrame 示例中设置断点

的调用堆栈面板 启用异步 后

带有异步调用堆栈的 requestAnimationFrame 示例中设置的断点

启用异步

使用 MutationObserver 时跟踪 DOM 更新

MutationObserver 允许我们观察 DOM 的变化。 在这个 简单的例子 中,当你点击按钮时,一个新的 DOM 节点被追加到 <div class="rows"></div>

在里面添加断点 nodeAdded()(第 31 行)在 demo.html 中。 启用异步调用堆栈后,您现在可以遍历调用堆栈 addNode() 到初始点击事件。

在没有异步调用堆栈的 mutationObserver 示例中设置断点

的调用堆栈面板 启用异步

带有异步调用堆栈的 mutationObserver 示例中设置的断点

启用异步

在异步调用堆栈中调试 JavaScript 的技巧

命名你的函数

如果您倾向于将所有回调分配为匿名函数,则可能希望为它们命名,以便更轻松地查看调用堆栈。例如,采用这样的匿名函数:

window.addEventListener('load', function(){
   // 做一点事
 }); 

并给它起一个名字 windowLoaded():

window.addEventListener('load', function windowLoaded (){ 
   // 做一点事 
 }); 

当 load 事件触发时,它将以其函数名称而不是神秘的匿名函数,显示在 DevTools 堆栈跟踪中。 这使得一目了然地查看堆栈跟踪中发生的事情变得更加容易。

匿名函数

命名函数

进一步探索

回顾一下,这些是 DevTools 将在其中显示完整调用堆栈的所有异步回调:

  • Timers:走回哪里 setTimeout()或者 setInterval()被初始化。
  • XHRs :走回哪里 xhr.send()被称为。
  • Animation frames:回到调用 requestAnimationFrame 的位置。
  • Promises : 回到 promise 被解决的地方。
  • Object.observe :回到观察者回调最初绑定的位置。
  • MutationObservers :返回到触发突变观察者事件的位置。
  • window.postMessage() :遍历进程内消息调用。
  • DataTransferItem.getAsString()
  • FileSystem API
  • IndexedDB
  • WebSQL
  • 符合条件的 DOM 事件通过 addEventListener():回到触发事件的地方。 由于性能原因,并非所有 DOM 事件都符合异步调用堆栈功能。 当前可用事件的示例包括:scroll、hashchange 和 selectionchange。
  • 多媒体活动通过 addEventListener():回到触发事件的地方。 可用的多媒体事件包括:音频和视频事件(例如 play、pause、ratechange)、WebRTC MediaStreamTrackList 事件(例如 addtrack、removetrack)和MediaSource 事件(例如'sourceopen')。

能够看到你的 JavaScript 回调的完整堆栈跟踪应该会让你头疼。 当多个异步事件相互关联时,或者从异步回调中抛出未捕获的异常时,DevTools 中的此功能将特别有用。

在 Chrome 中尝试一下。 如果您对此新功能有任何反馈,请在 Chrome DevTools 错误跟踪器 Chrome DevTools Group

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

孤檠

暂无简介

文章
评论
481 人气
更多

推荐作者

微信用户

文章 0 评论 0

小情绪

文章 0 评论 0

ゞ记忆︶ㄣ

文章 0 评论 0

笨死的猪

文章 0 评论 0

彭明超

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文