Web Worker
是HTML5
提出的新标准,为 JavaScript 创造多线程环境,容许主线程建立 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,二者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(一般负责 UI 交互)就会很流畅,不会被阻塞或拖慢。html
1.性能上要注意nginx
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(好比用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通讯。可是,这也形成了 Worker 比较耗费资源,不该该过分使用,并且一旦使用完毕,就应该关闭。web
2.同源限制chrome
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。浏览器
3.DOM限制网络
Worker 线程所在的全局对象,与主线程不同,没法读取主线程所在网页的 DOM 对象,也没法使用document
、window
、parent
这些对象。可是,Worker 线程能够navigator
对象和location
对象。多线程
4.通讯联系函数
Worker 线程和主线程不在同一个上下文环境,它们不能直接通讯,必须经过消息完成。post
5.脚本限制性能
Worker 线程不能执行alert()
方法和confirm()
方法,但可使用 XMLHttpRequest 对象发出 AJAX 请求。
6.文件限制
Worker 线程没法读取本地文件,即不能打开本机的文件系统(file://
),它所加载的脚本,必须来自网络。
关于这个demo又几点须要注意的地方。
因Web Worker
是HTML5的新标准因此ECMAScript的标准语法中并不支持,这个demo实在浏览器上进行测试,支持HTML的浏览器除IE外都能很好的兼容Web Worker
,IE10部分兼容。我这里选择的chrome进行测试。
因为Worker构造函数 不能读取本地文件,关于worker线程的脚本文件须要经过网络下载,不然会报404(这点须要特别注意下)
为了顺利测试解决worker线程的脚本须要经过网络下载的问题这里我将WebWorkerDemo部署到本机的nginx上面使用chrom进行访问
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <button id="btn1">start worker!</button> <button id="btn2">postMessage Main====>worker</button> <button id="btn3">stop worker!</button> <script src="main.js"></script> </body> </html>
main.js
(function() { let startWorker = document.querySelector('#btn1'); let postMessage = document.querySelector('#btn2'); let stopWorker = document.querySelector('#btn3'); let worker; let data = 10; startWorker.addEventListener('click', () => { worker = new Worker('worker1.js'); worker.addEventListener('message', (event) => { console.log(event.data); if (!event.data) { console.log('closes worker thread'); worker.terminate(); } }, false); }); postMessage.addEventListener('click', () => { worker.postMessage(data); }); stopWorker.addEventListener('click', () => { worker.terminate(); }); }());
worker1.js
(function () { console.log('start worker'); this.addEventListener('message', (event) => { let count = event.data; setInterval(() => { postMessage(count--); }, 1000); }, false); }());
了解一下