阮大神教程
webwork简介
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
webwork使用注意事项
同源限制
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
DOM 限制
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。
通信联系
Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
脚本限制
Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。
示例:.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><script></script></head><body><!--1、h5 规范提供了js分现成的实现,取名为:web Workers2、相关APIWorker:构造函数,加载分线程执行的js文件Worker.prototype.onmessage: 用于接收另一个线程的回调函数Worker.prototype.postMessage: 向另一个线程发送消息3、不足worker内代码不能操作DOM(更新UI)不能跨域加载JS不是每个浏览器都支持这个新特性web Workers 是HTML5提供的一个javascript多线程解决方案我们可以将一些大计算量的代码交给由web Worker运动而不冻结用户界面但是子线程完全受主线程控制,且不得操作DOM。所以这个新标准并没有改变Javascript单线程的本质。--><input type="text" id="input1" placeholder="输入数字" /><button id="btn1">计算</button></body><script>window.onload = function () {var oInput = document.getElementById("input1");var oBtn = document.getElementById("btn1");oBtn.onclick = function () {//数字太大的话,会让主线程卡死var worker = new Worker("work2.js");worker.onmessage = function (event) {console.log("主线程接收分线程返回的数据:" + event.data);worker.terminate(); //关闭线程};//向分线程发送消息worker.postMessage(oInput.value);worker.addEventListener("error", function(event){console.log(event);})//或者/*worker.addEventListener('error', function (event) {// ...});*/};};//完成任务以后主线程就可以把它关掉了</script></html>
work2.js
function Fibonacci(n) {if (n <= 1) {return n;}return Fibonacci(n - 1) + Fibonacci(n - 2);}// onmessage = function(event){// var result = event.data;// //可以通过data拿到我们想要的数据// postMessage(Fibonacci(result));// //可以使用下述对象// // console.log(location);// // console.log(navigator)// //不可以使用 alert 等dom操作// console.log(alert);// }//写法1// self.addEventListener("message", function(event){// var result = event.data;// //可以通过data拿到我们想要的数据// postMessage(Fibonacci(result));// })// //写法2// this.addEventListener("message", function(event){// var result = event.data;// //可以通过data拿到我们想要的数据// postMessage(Fibonacci(result));// })//写法3addEventListener("message", function(event){var result = event.data;//可以通过data拿到我们想要的数据postMessage(Fibonacci(result));// self.close(); //用于Worker内部关不自身importScripts('work3.js')})//写法4// onmessage = function(event){// var result = event.data;// //可以通过data拿到我们想要的数据// postMessage(Fibonacci(result));// //可以使用下述对象// // console.log(location);// // console.log(navigator)// //不可以使用 alert 等dom操作// console.log(alert);// }
数据通信
前面说过,主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。需要注意的是,这种通信是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原。主线程与 Worker 之间也可以交换二进制数据,比如 File、Blob、ArrayBuffer 等类型,也可以在线程之间发送。下面是一个例子。
