📅  最后修改于: 2020-10-23 06:20:29             🧑  作者: Mango
JavaScript被设计为在单线程环境中运行,这意味着多个脚本不能同时运行。考虑一种情况,您需要处理UI事件,查询和处理大量API数据以及操纵DOM。
如果CPU使用率很高,JavaScript会挂起您的浏览器。让我们举一个简单的示例,其中JavaScript经历一个大循环-
Big for loop
它将产生以下结果-
当您单击Big Loop按钮时,它将在Firefox中显示以下结果-
可以使用Web Worker处理上述情况, Web Worker将执行所有计算量大的任务,而不会中断用户界面,并且通常在单独的线程上运行。
Web Workers允许长时间运行的脚本不会被响应单击或其他用户交互的脚本打断,并允许执行长时间的任务而不会使页面保持响应状态。
Web Workers是后台脚本,并且相对较重,不打算大量使用。例如,为四百万像素图像的每个像素启动一个工作程序是不合适的。
在Web Worker中执行脚本时,它无法访问网页的窗口对象(window.document),这意味着Web Worker无法直接访问网页和DOM API。尽管Web Workers不能阻止浏览器UI,但是他们仍然可以消耗CPU周期并降低系统响应速度。
Web Workers使用JavaScript文件的URL初始化,其中包含该Worker将执行的代码。此代码设置事件侦听器,并与从主页派生事件的脚本进行通信。以下是简单的语法-
var worker = new Worker('bigLoop.js');
如果指定的javascript文件存在,浏览器将生成一个新的工作线程,该线程异步下载。如果工作线程的路径返回404错误,则工作线程将静默失败。
如果您的应用程序具有多个支持的JavaScript文件,则可以将其导入importScripts()方法,该方法以文件名作为参数,并以逗号分隔,如下所示-
importScripts("helper.js", "anotherHelper.js");
生成Web Worker后,将使用postMessage()方法完成Web Worker及其父页面之间的通信。根据您的浏览器/版本,postMessage()可以接受字符串或JSON对象作为其单个参数。
使用主页上的onmessage事件访问由Web Worker传递的消息。现在,让我们使用Web Worker编写我们的bigLoop示例。以下是主页(hello.htm),它将产生一个Web工作程序来执行循环并返回变量j的最终值-
Big for loop
以下是bigLoop.js文件的内容。这利用postMessage() API将通信传递回主页-
for (var i = 0; i <= 1000000000; i += 1) {
var j = i;
}
postMessage(j);
这将产生以下结果-
Web Workers不会自己停止,但是启动它们的页面可以通过调用Terminate()方法来停止它们。
worker.terminate();
终止的Web Worker将不再响应消息或执行任何其他计算。您无法重新启动工作程序;相反,您可以使用相同的URL创建一个新工作线程。
下面显示了Web Worker JavaScript文件中错误处理功能的示例,该函数将错误记录到控制台。使用错误处理代码,上面的示例将变为以下内容-
Big for loop
以下是检测浏览器中可用的Web Worker功能支持的语法-
Big for loop
这将产生以下结果-