当前位置: 首页 > 文档资料 > HTML5 入门教程 >

Web_Workers

优质
小牛编辑
130浏览
2023-12-01

JavaScript旨在在单线程环境中运行,这意味着多个脚本无法同时运行。 考虑一种情况,您需要处理UI事件,查询和处理大量API数据以及操作DOM。

JavaScript会在CPU利用率很高的情况下挂起您的浏览器。 让我们举一个简单的例子,JavaScript经历一个大循环 -

<!DOCTYPE HTML>
<html>
   <head>
      <title>Big for loop</title>
      <script>
         function bigLoop() {
            for (var i = 0; i <= 10000; i += 1) {
               var j = i;
            }
            alert("Completed " + j + "iterations" );
         }
         function sayHello(){
            alert("Hello sir...." );
         }
      </script>
   </head>
   <body>
      <input type = "button" onclick = "bigLoop();" value = "Big Loop" />
      <input type = "button" onclick = "sayHello();" value = "Say Hello" />
   </body>
</html>

单击“大循环”按钮时,它会在Firefox中显示以下结果 -

大循环

什么是Web Workers?

上面解释的情况可以使用Web Workers来处理,他们将在不中断用户界面的情况下执行所有计算上昂贵的任务,并且通常在不同的线程上运行。

Web Workers允许长时间运行的脚本不受响应点击或其他用户交互的脚本中断,并允许执行长任务而不会让页面保持响应。

Web Workers是后台脚本,它们相对较重,并不打算大量使用。 例如,为四百万像素图像的每个像素启动一个工作人员是不合适的。

当脚本在Web Worker中执行时,它无法访问网页的窗口对象(window.document),这意味着Web Workers无法直接访问网页和DOM API。 尽管Web Workers无法阻止浏览器UI,但它们仍然会消耗CPU周期并使系统响应性降低。

Web工作者如何工作?

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 worker来执行循环并返回变量j的最终值 -

<!DOCTYPE HTML>
<html>
   <head>
      <title>Big for loop</title>
      <script>
         var worker = new Worker('bigLoop.js');
         worker.onmessage = function (event) {
            alert("Completed " + event.data + "iterations" );
         };
         function sayHello() {
            alert("Hello sir...." );
         }
      </script>
   </head>
   <body>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

以下是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创建新工作线程。

处理错误 (Handling Errors)

下面显示了Web Worker JavaScript文件中的错误处理函数示例,该函数将错误记录到控制台。 使用错误处理代码,上面的示例将变为如下 -

<!DOCTYPE HTML>
<html>
   <head>
      <title>Big for loop</title>
      <script>
         var worker = new Worker('bigLoop.js');
         worker.onmessage = function (event) {
            alert("Completed " + event.data + "iterations" );
         };
         worker.onerror = function (event) {
            console.log(event.message, event);
         };
         function sayHello() {
            alert("Hello sir...." );
         }
      </script>
   </head>
   <body>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

检查浏览器支持

以下是检测浏览器中可用的Web Worker功能支持的语法 -

<!DOCTYPE HTML>
<html>
   <head>
      <title>Big for loop</title>
      <script src = "/js/modernizr-1.5.min.js"></script>
      <script>
      function myFunction() {
         if (Modernizr.webworkers) {
            alert("Congratulation!! you have web workers support." );
         } else {
            alert("Sorry!! you do not have web workers support." );
         }
      }
      </script>
   </head>
   <body>
      <button onclick = "myFunction()">Click me</button>
   </body>
</html>