今天这篇内容主要讲述HTML 5 Web Worker(一种支持前端js多线程的技术)。javascript
W3C 在 HTML5 的规范中提出了工做线程(Web Worker)的概念,工做线程容许开发人员编写可以长时间运行而不被用户所中断的后台程序, 去执行事务或者逻辑,并同时保证页面对用户的及时响应。
工做线程的出现使得在 Web 页面中进行多线程编程成为可能。众所周知,传统页面中(HTML5 以前)的 JavaScript 的运行都是以单线程的方式工做的,虽然有多种方式实现了对多线程的模拟(例如:JavaScript 中的 setinterval 方法,setTimeout 方法等),可是在本质上程序的运行仍然是由 JavaScript 引擎以单线程调度的方式进行的。在 HTML5 中引入的工做线程使得浏览器端的 JavaScript 引擎能够并发地执行 JavaScript 代码,从而实现了对浏览器端多线程编程的良好支持。html
Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,而且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。前端
Web Worker 能够分为两种不一样线程类型,一个是专用线程 Dedicated Worker,一个是共享线程 Shared Worker。两种类型的线程各有不一样的用途。下面仅仅对专用工做线程作简要描述。
Web worker的运行原理和两种线程的详细说明请查看这里。java
它是专用线程的执行文件,即复杂的运算都在这里执行,onmessage接收主线程发送来的消息(参数),并将运行结果postMessage回主线程。web
if(typeof(Worker)!=="undefined")
在建立专用线程的时候,须要给 Worker 的构造函数提供一个指向 JavaScript 文件资源的 URL,这也是建立专用线程时 Worker 构造函数所须要的惟一参数。当这个构造函数被调用以后,一个工做线程的实例便会被建立出来。下面是建立专用线程代码示例:编程
var worker = new Worker(jsrefurl);
worker.onmessage = function (event) { ... };
worker.postMessage();
当咱们建立 web worker 对象后,它会继续监听消息(即便在外部脚本完成以后)直到其被终止为止。
如需终止 web worker,并释放浏览器/计算机资源,请使用 terminate() 方法:浏览器
worker.terminate();
下面咱们使用一个示例说明上述过程。多线程
新建外部web worker 的js文件,命名为webworker.js并发
onmessage = function (event) { var msg = event.data; for (var i = 0 ; i < msg; i++) { if (!!console && i % 500 == 0) { console.info(i); } } var d = new Date(); postMessage(d); }
新建主线程页面,命名为webworker.html函数
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> web worker实时时间:<div id="workerTime"></div> <br /> 主线程获取当前时间:<div id="curTime"></div> <button onclick="mainthread()">主线程获取时间</button> <script> var interval; if (typeof Worker != undefined) { var worker = new Worker("webworker1.js"); worker.onmessage = function (event) { document.getElementById("workerTime").textContent = event.data; } interval = setInterval('worker.postMessage("1000000")', 1000); } function mainthread() { document.getElementById("curTime").textContent = new Date(); } function stop() { clearInterval(interval);
worker.terminate(); } setTimeout(stop, 60000);//60秒以后清理interval </script> </body> </html>
代码很简单,只是为了说明webworker线程不会阻塞主线程(即实现前端多线程)。
示例中咱们将webworker线程设置interval不断发起请求,使用一个循环在模仿复杂操做,或者你也能够在js中加入其余操做来模拟耗时操做。
定义了一个按钮,在主线程中获取当前时间。咱们能够随时点击该按钮调用主线程的方法,而其不会受到web worker线程的影响。
运行效果我就不贴图了,各园友粘贴代码便可运行查看效果。
因为 web worker 位于外部文件中,它们没法访问下列 JavaScript 对象:
本文示例很简单,可是麻雀虽小五脏俱全。
主线程新建web worker,发送消息及接收消息,web worker 接收及反馈消息,主线程主动中止web worker线程等全都使用到了。
相信看完这个简介和示例,对web worker也有了必定掌握。