关于Web Worker你必须知道的7件事

介绍

通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程。Web Worker可以提高应用的总体性能,并且提升用户体验。如果你想在自己的Web应用中使用Web Worker, 不妨来了解一下有关Web Worker的7件事。

1. Web Worker 可以让你在后台运行Javascript

一般来说Javascript和页面的UI会共用一个线程,所以当点击一个按钮开始运行Javascript后,在这段代码运行完毕之前,页面是无法响应用户操作的,换句话来说就是被“冻结”了。而这段代码可以交给Web Worker在后台运行,那么页面在Javascript运行期间依然可以响应用户操作。后台会启动一个worker线程来执行这段代码,用户可以创建多个worker线程。所以你可以在前台做一些小规模分布式计算之类的工作,不过Web Worker有以下一些使用限制:

  • Web Worker无法访问DOM节点;
  • Web Worker无法访问全局变量或是全局函数;
  • Web Worker无法调用alert()或者confirm之类的函数;
  • Web Worker无法访问window、document之类的浏览器全局变量;

不过Web Worker中的Javascript依然可以使用setTimeout(),setInterval()之类的函数,也可以使用XMLHttpRequest对象来做Ajax通信。

2. 有两种Web Worker

Web workers可分为两种类型:专用线程dedicated web worker,以及共享线程shared web worker。 Dedicated web worker随当前页面的关闭而结束;这意味着Dedicated web worker只能被创建它的页面访问。与之相对应的Shared web worker可以被多个页面访问。在Javascript代码中,“Work”类型代表Dedicated web worker,而“SharedWorker”类型代表Shared web worker。

在绝大多数情况下,使用Dedicated web worker就足够了,因为一般来说在web worker中运行的代码是专为当前页面服务的。而在一些特定情况下,web worker可能运行的是更为普遍性的代码,可以为多个页面服务。在这种情况下,我们会创建一个共享线程的Shared web worker,它可以被与之相关联的多个页面访问,只有当所有关联的的页面都关闭的时候,该Shared web worker才会结束。相对Dedicated web worker,shared web worker稍微复杂些。

3. “Worker”对象代表Dedicated Web Worker

现在来看如何使用Dedicated web worker。下面的例子中用到了jQuery以及Modernizr作为Javascript库,然后往HTML页面中加入以下代码:

[html] view plaincopy

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title></title>
  5. <script type="text/javascript" src="script/modernizr.js"></script>
  6. <script type="text/javascript" src="script/jquery-2.0.0.js"></script>
  7. <script type="text/javascript">
  8. $(document).ready(function(){
  9. if(!Modernizr.webworker){
  10. alert("This browser doesn‘t support Web Worker!");
  11. return;
  12. }
  13. $("#btnStart").click(function(){
  14. var worker = new Worker("script/lengthytask.js");
  15. worker.addEventListener("message", function(evt){
  16. alert(evt.data);
  17. }, false);
  18. worker.postMessage(10000)
  19. });
  20. });
  21. </script>
  22. </head>
  23. <body>
  24. <form>
  25. <input type="button" id="btnStart" value="Start Processing"/>
  26. </form>
  27. </body>
  28. </html>

这个HTML页面中有个按钮,点击后会运行一个Javascript文件。上面的代码中首先检测当前浏览器是否支持Web Worker,不支持的话,就跳出提醒信息。

按钮的点击事件中创建了Worker对象,并给它指定了Javascript脚本文件——lengthytask.js(稍后会有代码),并且给Worker对象绑定了一个“message”事件。该事件会在后台代码(lengthytask.js)向页面返回数据时触发。“message”事件可以通过event.data来获取后台代码传回的数据。最后,postMessage方法正式执行lengthytask.js,该方法还可以向后台代码传递参数, 后台代码同样通过message事件获取该参数。

下面是lengthytask.js主要包含的代码:

[javascript] view plaincopy

  1. addEventListener("message", function(evt){
  2. var date = new Date();
  3. var currentDate = null;
  4. do {
  5. currentDate = new Date();
  6. }while(currentDate - date < evt.data);
  7. postMessage(currentDate);
  8. }, false);

以上代码在后台监听message时间,并获取页面传来的参数:10000;这里实际上是一个计时函数:在message事件被触发10000毫秒之后,把结果(currentDate)传给页面。

所以当点击“Start Processing”按钮,页面会在10秒钟后把当时的时刻alert出来。在这10秒钟内页面依然可以响应鼠标键盘事件。

4. “SharedWorker”对象代表Shared Web Worker

前面的代码使用的是dedicated web worker。 这一节会用shared web worker代替dedicated web worker,来区别两者的不同。下面是同一个例子的shared web worker版本:

[javascript] view plaincopy

  1. addEventListener("message", function(evt){
  2. var date = new Date();
  3. var currentDate = null;
  4. do {
  5. currentDate = new Date();
  6. }while(currentDate - date < evt.data);
  7. postMessage(currentDate);
  8. }, false);

请注意加黑的代码,这里创建了一个SharedWorker对象,并把message事件绑定在shared worker的port对象上;同样由port对象发起postMessage, 开始执行后台代码sharedlengthytask.js。

下面是sharedlengthytask.js的主要代码:

[javascript] view plaincopy

  1. var port;
  2. addEventListener("connect", function(evt){
  3. port = evt.ports[0];
  4. port.addEventListener("message", function(evt){
  5. var date = new Date();
  6. var currentDate = null;
  7. do {
  8. currentDate = new Date();
  9. }while(currentDate - date < evt.data);
  10. port.postMessage(currentDate);
  11. }, false);
  12. port.start();
  13. }, false);

使用SharedWorker对象的后台代码需要绑定connect和message事件, connect事件会在页面上的port被start时触发。之后的message事件的回调函数与之前的基本相同,最后port调用postMessage方法把结果传回给页面。

5. Web Worker使用XMLHttpRequest与服务端通信

有些情况下,web worker还需要与服务器进行交互。比如页面可能需要处理来自数据库中的信息,我们就需要使用Ajax技术与服务器交互,下面代码包含了web worker如何从服务端获取数据:

[javascript] view plaincopy

  1. addEventListener("message", function(evt){
  2. var xhr = new XMLHttpRequest();
  3. xhr.open("GET", "lengthytaskhandler.ashx");
  4. xhr.onload = function(){
  5. postMessage(xhr.responseText);
  6. };
  7. xhr.send();
  8. },false);

上面的代码向服务端的asp.net服务lengthytaskhandler.ashx发出GET请求。并注册了获取数据后的onload事件。下面的代码是服务端的lengthytaskhandler.ashx:

[csharp] view plaincopy

  1. namespace WebWorkerDemo
  2. {
  3. public class LengthyTaskHandler:IHttpHandler
  4. {
  5. public void ProcessRequest(HttpContext context)
  6. {
  7. System.Threading.Thread.Sleep(10000);
  8. context.Response.ContentType = "text/plain";
  9. content.Response.Write("Processing successful!");
  10. }
  11. public bool IsReusable
  12. {
  13. get
  14. {
  15. return false;
  16. }
  17. }
  18. }
  19. }

如你所见,ProcessRequest模拟了一个长时间运行的任务,并返回了“Processing successful!”的消息。

6. 通过Error事件捕捉错误信息

当我们把越来越复杂的逻辑加到Web Worker里时,错误处理机制是必不可少的。而Web Worker恰恰提供了error事件,供开发者捕捉错误信息。下面的代码展示了如何绑定error事件:

[javascript] view plaincopy

  1. $("#btnStart").click(function(){
  2. var worker = new Worker("scripts/lengthytask.js");
  3. worker.addEventListener("error", function(evt){
  4. alert("Line #" + evt.lineno + " - " + evt.message + " in " + evt.filename);
  5. }, false);
  6. worker.postMessage(10000);
  7. });

如上可见, Worker对象可以绑定error事件;而且evt对象中包含错误所在的代码文件(evt.filename)、错误所在的代码行数(evt.lineno)、以及错误信息(evt.message)。

7. 通过terminate()方法终止Web Worker

有些情况下,我们可能需要强制终止执行中的Web Worker。Worker对象提供了terminate()来终止自身执行任务,被终止的Worker对象不能被重启或重用,我们只能新建另一个Worker实例来执行新的任务。

总结

Web Worker可以在后台执行脚本,而不会阻塞页面交互。Worker对象分为两种:专用式Web Worker和共享式Web Worker:专用式的Web Worker只能被当个页面使用,而共享式的Web Worker可以在被多个页面使用。另外,本文还介绍了Web Worker的错误处理机制,以及使用Ajax与服务端交互。

时间: 2024-12-21 04:23:22

关于Web Worker你必须知道的7件事的相关文章

歪果仁眼中的中国科技界必须知道的7件事

注:本文来自Medium, 中文版由天地会珠海分舵编译.文章中有些观点可能存在偏颇,请读者自行决断. 中国是个神奇的国度,有很多东西是歪果仁所不知道的.以下列出在中国科技界你必须知道的7个事实. 中国13亿人中有一半没有网络接入 一个正在打电话的农民所用的是功能机,而非智能手机. 根据最近的一次研究,47.9%的中国人是没有接入互联网的.但中国的一些互联网初创企业及一些大企业却跟投资人和客户说,他们的目标是占领13亿用户市场.他们这样做是把这些看不见的用户也算在的他们的商业计划里面以愚弄投资人.

开发第一个Android应用前你必须知道的5件事

英文原文:5 THINGS TO KNOW BEFORE BUILDING YOUR FIRST ANDROID APP 我最近刚刚阅读了 Praneeth VT 发表在 Reddit 上的一个帖子,是关于他如何开发自己第一款 Android 手机应用--一个 GPA 计算器的.可以看出来他在这个编程世界还是新手,所以我想深入探讨一下他是如何做到的,以便于大家学习和借鉴. 在此之前,我想先介绍一下 Praneeth VT. 毕业于计算机工程专业 实际上,他才总共学了为期 6 个月的编程课 在上了

投身移动开发必须知道的20件事

1.选择你的平台 选择什么样的平台取决于你想做什么以及你的用户是谁.这些平台的最顶层是web.如果你想出售你的应用程序,那么你可能想要将它放在应用商店.如果你需要使用相机或者其他设备的API,那么你可以使用本地方法,或者使用一些封装好了的框架比如AIR/PhoneGap/Titanium. 这里没有明确的答案,你选择什么样的平台取决于很多的事情,因此不妨回顾一下贴在墙上的那些话,也许它们会告诉你答案. 2.甭想快速暴富 很多人对比了当前的应用商店的热潮和19世纪40年代末的加利福尼亚淘金热,正如

有理想的程序员必须知道的15件事

作为程序员,要取得非凡成就需要记住的15件事. 1.走一条不一样的路 在有利于自己的市场中竞争,如果你满足于"泯然众人矣",那恐怕就得跟那些低工资国家的程序员们同场竞技了. 2.了解自己的公司 以我在医院.咨询公司.物流企业以及大技术公司工作的经验来看,这一点所言不虚. 不同公司的运营模式差异极大.如果你理解企业的运营模式,那你就不一样了!在这家公司中(或者对客户而言),你是参与业务运营的资产,你的工作能直接产生效益! 3.与最优秀的人为伍 很早以前,我喜欢打篮球,被分配到一个水平比较

关于DevOps你必须知道的11件事

转自:http://www.infoq.com/cn/articles/11devops 关于作者 Gene Kim在多个角色上屡获殊荣:CTO.研究者和作家.他曾是Tripwire的创始人并担任了13年的CTO.他写过两本书,其中包括<The Visible Ops Handbook>,目前他正在编写<The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win>和<DevOps C

PP开发新手--你必须知道的5件事

在APP商店当中,每个APP就像是九牛一毛.假如你想让你的APP锋芒毕露,那么就必须知道下面这些东西: 1.仿照并不是老是有用 假如你的产品极好,那么其他人就会copy你的产品,而且产品越好,这种可能性越高.这是第一点要记住的.所以假如你有了一个好产品,那就好谋划一个强有力的发布方案了.并赶快获得用户基数,这是对抗今后仿照者的根本.你的用户越多,产品的基础就越牢固.而且还有能够升级为付费用户. 2.在移动应用的国际中,APP太容易迷失了 一切开发者都要面临的挑战是,如何让自个的产品被用户发现.要

【必看】Security+认证必须知道的8件事

Security+属于信息安全技能认证,CompTIA Security+ 较重视技术与操作层面,包括系统.主机.应用程序.数据和网络等基础性的安全问题,基本的加密方法和评估审计知识.与CISSP一起并列为全球最具影响力的十大IT认证,并被CertCities.com排为IT业10大热门认证.而且Security+ 已连续3年都在前10名以内,属于信息安全技术类的首选认证. Security+最近这么火热,问小微的小伙伴也越来越多了,今天小微总结出关于Security+认证5大问题,希望可以帮助

每一个C#开发者必须知道的13件事情

1.开发流程 程序的Bug与瑕疵往往出现于开发流程当中.只要对工具善加利用,就有助于在你发布程序之前便将问题发现,或避开这些问题. 标准化代码书写 标准化代码书写可以使代码更加易于维护,尤其是在代码由多个开发者或团队进行开发与维护时,这一优点更加突出.常见的强制代码规范化的工具有:FxCop.StyleCop和ReSharper. 开发者语:在掩盖错误之前请仔细地思考这些错误,并且去分析结果.不要指望依靠这些工具来在代码中寻找错误,因为结果可能和你的与其相去甚远. 代码审查 审查代码与搭档编程都

C#开发者必须知道的13件事情

1.开发流程 程序的Bug与瑕疵往往出现于开发流程当中.只要对工具善加利用,就有助于在你发布程序之前便将问题发现,或避开这些问题. 标准化代码书写 标准化代码书写可以使代码更加易于维护,尤其是在代码由多个开发者或团队进行开发与维护时,这一优点更加突出.常见的强制代码规范化的工具有:FxCop.StyleCop和ReSharper. 开发者语:在掩盖错误之前请仔细地思考这些错误,并且去分析结果.不要指望依靠这些工具来在代码中寻找错误,因为结果可能和你的与其相去甚远. 代码审查 审查代码与搭档编程都