如何调试Web Workers

86
我一直在使用HTML 5中的Web Workers,并正在寻找调试它们的方法。理想情况下像Firebug或Chrome调试器那样的工具。有没有什么好的解决方案呢?由于无法访问控制台或DOM,要调试可能有问题的代码有些困难。

2
你尝试在你想要断点的那一行之前加入 debugger;了吗? - Ruan Mendes
嗯,整个重点是Firebug和Web工具无法访问Worker。 - Zachary K
13
Chrome的Web Inspector有一个名为“Scripts”的选项卡;在其中,有一个折叠面板内的面板标为“Worker Inspectors”,里面有一个名为“Debug”的复选框。我不确定它是否有效,但还是值得一试的,你尝试过了吗?或者你百分之百确定它行不通? - Ruan Mendes
@JuanMendes,在哪里?截图。这对SharedWorker有效吗? - Pacerier
@Pacerier 自从留言以来它已经改变,请尝试导航到chrome://inspect/#workers - Ruan Mendes
显示剩余2条评论
14个回答

58

Chrome的Dev频道版本支持通过注入模拟使用iframe的假工作者实现工作者的调试。您需要导航到脚本窗格并在右侧的Workers侧边栏上勾选Debug复选框,然后重新加载页面。然后,工作脚本将出现在页面脚本列表中。但是,这种模拟有一定的局限性--由于工作者脚本将在客户端页面线程中运行,因此工作者中的任何长时间运行的操作都会冻结浏览器UI。


Chrome 17 是第一个支持 Web Worker 调试的版本。 - Bnicholas
11
前往 chrome://inspect 似乎是最好的选择。它可以让您为共享工作者的运行时打开一个控制台。 - Alec Hewitt
@AlecHewitt 你是怎么做到的?我在那里找不到任何共享工作者。 - YetAnotherBot
Firefox͏͏?? - Pacerier

33

WebWorker可以像普通网页一样进行调试。Chrome在chrome://inspect/#workers提供了WebWorker的调试工具。

找到需要调试的正在运行的WebWorker,然后点击“检查”。将会打开一个专门用于该WebWorker的调试工具窗口。官方的说明值得参考。


最好解释一下你的答案,否则它很可能不会有用或被接受。 - James Woolfenden
1
谢谢James。详细说明。 - user2519809
Web workers并不在上面的答案所说的地方适用于我,但是这个方法有效,谢谢。 - jamylak
现在 chrome://inspect/#workers 只显示 SharedWorkers,没有 Dedicated Workers。 - hldev

27
作为缺失 console.log 的快速解决方案,您可以直接使用 throw JSON.stringify({data:data})

3
当然,由于抛出异常,这将在你进行调试的地方停止执行。 - jimhigson
另请参阅werker.onerror及其相关内容。这至少可以轻松获取回溯信息。 - meawoppl

21

从Chrome 65开始,您现在可以直接使用调试器的“单步进入”功能:

在此输入图片描述

更多详细信息,请参见他们的发布说明


1
它在 Chrome 83.0.4103.116 上无法工作。我按了许多次“单步执行”(F11),但它仅停留在调用者/postMessage,而不进入被调用者/worker代码。 - WestCoastProjects
这确实有效,如果调用函数是async的话(请注意,截图/视频并没有显示它为异步..)。否则它就不起作用。 - WestCoastProjects

12

在Chrome v35中

  • 加载您的页面并打开Chrome开发者工具。

  • 导航到 Sources 选项卡。

  • 勾选 Pause on Start 复选框,如下所示:

    在Chrome开发者工具中调试工作线程

  • 重新加载页面,调试器将会停在Web Worker中,但在新窗口中!

编辑:在更新的Chrome版本中(我正在使用v39),工作者位于“ Threads” 选项卡下,而不是拥有自己的“ Workers”选项卡(如果有任何运行中的工作者,则“ Threads”选项卡将变为可见)。


5
无法在Chrome 38 Ubuntu上找到它。 - Steel Brain
3
找不到它。甚至没有名为“Workers”的子面板。 - Pacerier
火狐浏览器? - Pacerier

11
在Chrome调试器中的脚本选项卡中,滚动到Worker面板并选择“启动时暂停”选项。这将允许您调试Worker,并插入断点,但您需要在不同的窗口中完成所有操作。

火狐浏览器? - Pacerier

9
您可以使用 self.console.log('您的调试信息')

2

一种简单的解决方案,以便从工作线程中获取消息/数据进行调试的目的是使用postMessage(),从工作线程中传回所需的调试信息。

然后,这些消息可以在父进程的onmessage处理程序中“捕获”,例如将从工作线程传回的消息/数据记录到控制台。这具有非阻塞的优点,并允许工作进程作为真实线程运行并在通常的浏览器环境中进行调试。虽然这样的解决方案不能启用对工作进程代码的断点级别检查,但对于许多情况,它提供了从工作进程内部公开所需的尽可能多或尽可能少数量的数据来帮助调试。

一个简单的实现可能如下所示(显示相关摘录):

// 在工作线程的onmessage函数范围中的某个位置(根据需要使用):

postMessage({debug:{message:"This is a debug message"}});

// 在父级的 onmessage 处理程序中:

myWorker.onmessage = function(event) {
   if(event.data && event.data.debug) {
      // handle debug message processing here...
      if(event.data.debug.message) {
         console.log("message from worker: %o", event.data.debug.message);
      }
   } else {
      // handle regular message processing here...
   }
};

2
接受的答案并不适用于所有人。
在这种情况下,您可以在Firefox的Web Workers中使用console.logconsole.debugconsole.error。请参见Bug#620935Bug#1058644
如果您在Chrome中,则可以像调试常规脚本一样调试Web Workers,如果您这样做,console.log将打印到您的选项卡中。但是,如果您的工作者是共享的,则可能要查看chrome:// inspect
额外提示:由于对JavaScript新手来说学习Workers相当困难,因此我编写了一个非常轻量级的包装器,为两种类型的Workers提供一致的API。它被称为{{link3:Worker-Exchange}}。

非常重要:这些日志不会出现在页面日志中,而是出现在浏览器控制台中(可通过CTRL+SHIFT+J或单击Web开发工具图标访问)。 - autra
@autra,感谢您提醒我更新这个答案,我刚刚加入了使用Chrome的方法并提到了Worker-Exchange。 - Steel Brain
但是你还没有解释在Firefox中应该查看浏览器控制台,而不是Web开发工具的常规控制台。顺便说一下,不错的API!你可能想看看https://github.com/gaia-components/threads,它基本上做了同样的事情(还有其他功能),但还添加了iframe支持。 - autra

2
在最新版本的Google Chrome中,只需进入“开发者工具”>“资源”(或右键菜单>“检查”>“资源”)即可。
在左侧面板列表的底部,您将看到一个引擎图标中的服务工作者。

Service workers on Chrome 87


这并不能让你设置断点或逐步执行代码... - Slbox

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