关于webworkers你需要了解的七件事(代码片段)

刘星石 刘星石     2022-12-11     536

关键词:

介绍

Web Workers允许你在后台运行JavaScript代码,而不会阻止web用户界面。Web Workers可以提高网页的整体性能,还可以增强用户体验。Web Workers有两种风格 ——专用Web Workers和共享Web Workers。本文讨论了你所需要知道的Web worker的七个关键方面,帮助你决定在应用程序中使用它们的话。

1.Web Workers允许你在后台运行JavaScript代码

通常,你在Web页面中编写的JavaScript代码在与天津企业网站制作公司用户界面相同的线程中执行。这就是为什么当你点击一个会触发漫长处理过程的按钮,网页的用户界面会冻结。除非处理完成,否则你就无法工作于用户界面。Web worker允许你在后台执行JavaScript,以便用户界面保持响应,即使同时正在执行某些脚本。执行脚本的后台线程通常称为worker thread或worker。你可以生成尽可能多的worker,只要你想。你还可以将数据传递到正在worker thread中执行的脚本,并在完成时将值返回到主线程。然而,Web Workers有一些限制,如下所示:

  • Web Workers无法从web页面访问DOM元素。
  • Web Workers无法从web页面访问全局变量和JavaScript函数。
  • Web Workers不能调用alert()或confirm()函数。
  • 不能在Web Workers中访问诸如窗口,文档和parent这样的对象。

但是,你可以使用setTimeout(),setInterval()等函数。你也可以使用XMLHttpRequest对象向服务器发出Ajax请求。

2.Web Workers有两种类型

Web Workers有两种类型:专用Web Workers和共享Web Workers。专用Web Workers随同创建它们的网页一起存在和死亡。这意味着在网页中创建的专用Web Workers无法通过多个网页访问。另一方面,共享Web Workers在多个网页之间是共享的。Worker类代表专用Web Workers,而SharedWorker类代表共享Web Workers。

在许多情况下,专用Web Workers就可以满足你的需求。这是因为通常你需要在worker thread中执行一个网页的特定脚本。然而,有时,你需要在worker thread中执行一个脚本,并且这个worker thread对多个网页通用。在这种情况下,创建许多专用Web Workers,每个页面一个,还不如使用共享Web Workers。由一个网页创建的共享web worker仍然可用于其他网页。只有当所有到它的连接被关闭,才能毁坏它。共享Web Workers比专用Web Workers更复杂一点。

3.Worker对象代表专用Web Worker

现在,你了解了Web Workers的基础知识,让我们看看如何使用专用Web Workers。下面讨论的示例假设你已使用喜欢的开发工具创建了一个Web应用程序,并且还在其Script文件夹中添加了jQuery和Modernizr库。将HTML页面添加到web应用程序,然后键入以下代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="scripts/modernizr.js"></script>
    <script src="scripts/jquery-2.0.0.js"></script>
    <script type="text/javascript">         $(document).ready(function ()              if (!Modernizr.webworkers)                              alert("This browser doesn't support Web Workers!");                 return;                          $("#btnStart").click(function ()                  var worker = new Worker("scripts/lengthytask.js");                 worker.addEventListener("message", function (evt)                      alert(evt.data);                 ,false);                 worker.postMessage(10000);             );         );      </script>
</head>
<body>
    <form>
        <input type="button" id="btnStart" value="Start Processing" />
    </form>
</body>
</html>

上面的HTML页面包含一个触发一些JavaScript处理的按钮(btnStart)。请注意,该网页引用了Modernizr和jQuery库。<script>块包括ready()方法处理程序,并且该处理程序又反过来处理btnStart的单击事件。ready()处理程序首先检查浏览器是否支持web workers。这通过使用Modernizr的webworkers属性完成。如果浏览器不支持Web workers,则会向用户显示一条错误消息。

然后代码连接btnStart的点击事件处理程序。点击事件处理程序的代码很重要,因为它使用Worker对象在后台运行脚本。点击事件处理程序创建一个Worker对象并将其存储在本地变量——worker中。要在后台执行的JavaScript文件的路径在构造函数中传递。你将很快创建LengthyTask.js。然后,代码为Worker对象的消息事件添加一个事件处理程序。当目标脚本(在此情况下为LengthyTask.js)将一些值发送回网页时,会引发消息事件。消息事件处理函数可以使用evt.data属性来访问返回的值。最后,在Worker对象上调用postMessage()方法来触发LengthyTask.js的执行。 postMessage()方法还允许你将数据传递到目标脚本。在此示例中,将一个数字(10000)传递给postMessage(),postMessage()指示处理应持续的毫秒数量。你可以传递postMessage()调用中的任何其他数据,如JavaScript对象或字符串。

LengthyTask.js文件包含要在后台执行的代码,如下所示:

addEventListener("message", function (evt) 
    var date = new Date();
    var currentDate = null;
    do 
        currentDate = new Date();
     while (currentDate - date < evt.data);
    postMessage(currentDate);
, false);

上面的代码处理worker thread的消息事件。当主页面调用Worker对象上的postMessage()方法时,会引发消息事件。消息事件处理程序通过运行某些毫秒的do-while循环来模拟冗长的处理。此循环运行的毫秒数从主页传递(回忆前面讨论的postMessage())。因此,evt.data在此示例中返回10000。一旦长时间操作完成,代码调用postMessage()会把处理结果发送回主页面。在本例中,传递currentDate的值(currentDate是一个Date对象)。

如果你运行主网页并单击Start Processing按钮,那么你将在10秒后收到alert()。同时,页面的用户界面不会被阻止,你可以执行诸如滚动,点击等操作,表明来自LengthyTask.js的代码正在后台运行。

4. SharedWorker对象代表共享Web Worker

前面的示例使用了专用Web worker。让我们将同样的示例转换为使用共享Web worker。共享Web worker由SharedWorker对象表示。下面的代码显示了来自主页的代码的修改版本:

$(document).ready(function () 
  if (!Modernizr.webworkers)
  
    alert("This browser doesn't support Web Workers!");
    return;
  
  $("#btnStart").click(function () 
 var worker = new SharedWorker("scripts/sharedlengthytask.js"); worker.port.addEventListener("message", function (evt)  alert(evt.data); , false); worker.port.start(); worker.port.postMessage(10000);   );
);

注意用粗体字标记的代码。它创建了一个SharedWorker实例,并在构造函数中传递SharedLengthyTask.js。你将很快创建此文件。然后,代码将消息事件处理程序连接到SharedWorker对象的端口对象。消息处理程序函数执行与前面示例中相同的工作。然后代码在端口对象上调用start()方法。最后,在端口对象上调用postMessage()方法将数据(10000)发送到共享worker thread。

SharedLengthyTask.js文件包含以下代码:

var port;

addEventListener("connect", function (evt) 
    port = evt.ports[0];
    port.addEventListener("message", function (evt) 
        var date = new Date();
        var currentDate = null;
        do 
            currentDate = new Date();
         while (currentDate - date < evt.data);
        port.postMessage(currentDate);
    , false);
    port.start();
, false);

代码首先声明一个名为port的变量,用于存储端口对象的引用。这次处理了两个事件——connect和message。当与共享Web worker建立连接时,会触发connect事件。 connect事件处理程序捕获evt.port [0]对象并将其存储在之前声明的端口变量中。然后在端口对象上连接消息事件处理程序。调用端口对象的start()方法来开始侦听该端口上的消息。消息事件处理程序几乎与你在前面的示例中编写的消息事件处理程序相同,除了它附加到端口对象这一点。此外,在端口对象上调用postMessage(),以将处理结果发送到主页面。

5. Web Workers可以使用XMLHttpRequest与服务器通信

有时Web Worker可能需要与Web服务器通信。例如,你可能需要驻留在某些RDBMS中的数据以便于客户端处理。要完成此类任务,你可以使用XMLHttpRequest对象向服务器端资源发出请求。实例化Worker对象和处理消息事件的整个过程保持不变。但是,你需要向服务器端资源发出GET或POST请求。考虑下面的代码:

addEventListener("message", function (evt) 
 var xhr = new XMLHttpRequest(); xhr.open("GET", "lengthytaskhandler.ashx"); xhr.onload = function ()  postMessage(xhr.responseText); ; xhr.send(); , false);

上面显示的代码创建了XMLHttpRequest对象的实例。然后调用open()方法,并指定向服务器端资源LengthyTaskHandler.ashx(一个ASP.NET通用处理程序)发出GET请求。(虽然此示例使用ASP.NET通用处理程序,但你可以使用任何其他服务器端资源。)然后它处理XMLHttpRequest对象的load事件并调用postMessage()。 xhr.responseText作为postMessage()的参数。xhr.responseText将是ASP.NET通用处理程序作为响应返回的值。请求完成时引发load事件。

LengthyTaskHandler.ashx包含以下代码:

namespace WebWorkersDemo


    public class LengthyTaskHandler : IHttpHandler
    

        public void ProcessRequest(HttpContext context)  System.Threading.Thread.Sleep(10000); context.Response.ContentType = "text/plain"; context.Response.Write("Processing successful!"); 

        public bool IsReusable
        
            get
            
                return false;
            
        
    

正如你可以看到,ProcessRequest()通过在Thread类上调用Sleep()方法来模拟一些冗长的处理,并阻止执行10秒。然后它返回一个成功消息“Processing successful!”给调用者。如果你在进行这些更改后运行主网页,你会发现在10秒后,将显示一个包含此成功消息的警报对话框。

6.你可以使用错误事件捕获未处理的错误

如果你的Web worker正在进行一些复杂的操作,那么你可能需要添加错误处理到主网页代码,以便在worker中出现任何未处理错误时,可以采取适当的操作。这可以通过处理Worker对象的错误事件来完成。每当work thread中存在任何未处理的错误时,就会抛出错误事件。以下代码显示了如何完成此操作:

$("#btnStart").click(function () 
  var worker = new Worker("scripts/lengthytask.js");
  worker.addEventListener("message", function (evt) 
    alert(evt.data);
  , false);
 worker.addEventListener("error", function (evt)  alert("Line #" + evt.lineno + " - " + evt.message + " in " + evt.filename); , false);   worker.postMessage(10000);
);

从上面的代码可以看出,错误处理程序已经连接到worker对象的错误事件。错误处理函数接收一个事件对象,而该对象提供错误信息,例如发生错误的行号(evt.lineno),错误消息(evt.message)和发生错误的文件(evt.filename)。

7.你可以使用Terminate()方法终止worker

有时你可能会想要取消worker中正在执行的任务。对此,你可以通过调用其terminate()方法来摧毁Worker。一旦Worker终止,你就不能重新使用或重新启动它。当然,你总是可以创建另一个Worker实例并使用它。但请记住,terminate()会立即杀死了worker,并且不会给你任何机执行清理操作。

总结

Web workers允许你在后台执行脚本而不冻结网页用户界面。有两种类型——专用web worker和共享web worker。每个网页创建专用web worker,而跨多个网页使用共享web worker共享。Worker类代表专用web worker,SharedWorker类代表共享web worker。本文介绍了如何使用这两种类型,文中还讨论了如何处理错误以及webworker如何使用XMLHttpRequest与web服务器通信。

新手程序员应该知道的七件事

...码就应该掌握的,希望对新手程序员能够有帮助。  1.了解底层系统  软件 查看详情

javascript你应该知道的七件事(代码片段)

Javascript发展到今天,非常高兴看到她的成功。以前好多人都这么说:敲代码这么多年,如今最看不懂的程序是javascript!javascript尽管是一种弱类型语言,可是她却有着“高贵”的理论。以下是学习javascript过程中... 查看详情

安装完centos7后必做的七件事

...CentOS7后,首要的工作肯定是加强它的安全性,以下列出的七件事,是你进一步配置系统和安装其他软件前必须做的。1.更改root密码若果你是自行安装CentOS7的话,安装程序会让你自行设定root的密码。不过很多VPS服务商只会提供预... 查看详情

学习方法|买科研无人机之前你需要考虑的七件事

买科研无人机之前你需要考虑的七件事,很多客户都有买过我们的科研无人机P系列、Z系列等等...从最开始的P100,到后期的P200,再到现在的P450、P230、P600。2020年后,网络上也出现了更多种类和类型的科研无人机,... 查看详情

新手学习seo要做的七件事是什么?

...那么先进的编程,学习SEO不可能掌握网页设计,学习SEO不需要学习SEODIV+CSS;不是一个困难的任务,但是在学习过程中,如果你想掌握SEO,那么我们要做的几件事。1、学习SEO需要持之以恒的精神。为什么?学习SEO要有持之以恒的精... 查看详情

关于制造业中物联网的未来应该了解的7件事

在过去的十年间,物联网(IoT)和工业物联网(IIoT)一直是制造车间中的重要特征,而且这一趋势不会很快改变。根据Bsquare的年度调查,有86%的制造企业采用了不同形式的物联网来增强车间运营。这使得公平地认识到物联网... 查看详情

css翻译:“你需要了解的关于css的一切将改变财产”-3(代码片段)

查看详情

关于git,你需要了解这些(代码片段)

Introduction该文档用于汇总一些git的常用操作及开发规范,持续更新中…References整理项目开发中git三种常用的操作方式-zeeblogGit使用从入门到入土收藏吃灰系列(八)什么是分支分支的作用十分钟学会正确的github工作流,和开... 查看详情

关于git,你需要了解这些(代码片段)

Introduction该文档用于汇总一些git的常用操作及开发规范,持续更新中…References整理项目开发中git三种常用的操作方式-zeeblogGit使用从入门到入土收藏吃灰系列(八)什么是分支分支的作用十分钟学会正确的github工作流,和开... 查看详情

三:关于tcp

转自:http://www.jellythink.com/archives/705TCP是什么?具体的关于TCP是什么,我不打算详细的说了;当你看到这篇文章时,我想你也知道TCP的概念了,想要更深入的了解TCP的工作,我们就继续。它只是一个超级麻烦的协议,而它又是互... 查看详情

浅析webworker及实践(代码片段)

本文讲述内容如下所示:WebWorker概述APIWebWorker在实际项目中应用总结一、WebWorker概述1、WebWorker产生背景        众所周知JavaScript是单线程的语言,所有任务只能在一个线程上完成,一次只能做一件事,即前面... 查看详情

关于azuresql数据库你不知道的5件事

点击上方蓝字关注“汪宇杰博客”原文:AzureTipsandTricks翻译:汪宇杰AzureSQLDatabase如果您喜欢SQLServer,那么您可能也喜欢AzureSQL数据库。AzureSQL数据库是Azure中的SQLServer即服务。你负责处理数据,Azure负责运行和保护... 查看详情

关于session你需要了解这些

关于Session你需要了解这些session共享:1.各种web框架早已考虑到这个问题,比如asp.net,是支持通过配置文件修改session的存储介质为sqlserver的,所有机器的会话数据都从同一个数据库读,就不会存在不一致的问题;2.以cookie加密的... 查看详情

关于线程上下文切换,你知道多少?(代码片段)

点击关注公众号,实用技术文章及时了解由于现在大多计算机都是多核CPU,多线程往往会比单线程更快,更能够提高并发,但提高并发并不意味着启动更多的线程来执行。更多的线程意味着线程创建销毁开销加大... 查看详情

一文了解webworker(代码片段)

...AX、Promises、async/await 等技术,当然,本文要讲的WebWorker技术也可以实现异步编程。目前,主流的浏览器都支持WebWorker。二、WebWorker简介WebWorker是HTML5标准的一部分,这一规范定义了一套API,允许开发者在JavaScr... 查看详情

关于数据库,你可能最想知道的几件事

【CSDN编者按】随着技术不断更新,数据库的发展可谓全面开花,也吸引了越来越多人的关注,但大家真的都足够了解数据库吗?作者|易璜珵    责编|侯淼淼出品| 《新程序员》互联网飞速发展的时代里,数... 查看详情

关于数据库,你可能最想知道的几件事

【CSDN编者按】随着技术不断更新,数据库的发展可谓全面开花,也吸引了越来越多人的关注,但大家真的都足够了解数据库吗?作者|易璜珵    责编|侯淼淼出品| 《新程序员》互联网飞速发展的时代里,数... 查看详情

关于数据库,你可能最想知道的几件事

【CSDN编者按】随着技术不断更新,数据库的发展可谓全面开花,也吸引了越来越多人的关注,但大家真的都足够了解数据库吗?作者|易璜珵    责编|侯淼淼出品| 《新程序员》互联网飞速发展的时代里,数... 查看详情