使用 Chrome DevTools 调试异步 JavaScript 程序

发布于 2022-08-05 12:46:39 字数 8248 浏览 377 评论 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技术交流群

发布评论

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

关于作者

孤檠

暂无简介

0 文章
0 评论
479 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

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