js运行是单线程,每当页面中运行长时间的同步任务,会导致页面假死(卡顿),从而影响用户体验。
HTML5提出了Web Worker API,来实现web应用于主执行线程分离运行的脚本操作。即容许主线程创建worker线程,两者可以同时运行,相互不影响。
实现方式是另开一个单独的线程执行费事的js执行,从而使主线程(UI线程)不被阻塞。
Web Worker是浏览器为js提供了一个多线程的环境,并不是js本身支持多线程。
1、注意点
(1)Web Worker是由脚本创建的后台任务,任务执行中可以向其创建者收发信息。
(2)worker线程与主线程不在同一个上下文,不能直接通信,需要通过postMessage方法来通信。
(3)worker一旦新建,就会一直运行,易造成资源浪费,故完成运行,需要执行terminate关闭worker线程。
(4)分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。且Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络服务。
(5)无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。可以使用navigator对象和location对象。
2、worker的api
worker.postMessage: 主线程往worker线程发消息。
worker.terminate: 主线程关闭worker线程。
worker.onmessage: 指定worker线程发消息时的回调(也可以通过worker.addEventListener('message',cb)的方式)。
worker.onerror: 指定worker线程发生错误时的回调(也可以 worker.addEventListener('error',cb)的方法)。
3、方法实现
<p>计数: <output id="result"></output></p>
<button onclick="startWorker()">开始工作</button>
<button onclick="stopWorker()">停止工作</button>
<p><strong>注意:</strong> Internet Explorer 9 及更早 IE 版本浏览器不支持 Web Workers.</p>
<script>
var worker;function startWorker() {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
worker = new Worker("workers.js");
}
worker.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";
}
}
function stopWorker() {
worker.terminate();
worker = undefined;
}
</script>
// workers.js 为执行的脚本。
var i=0;
function timedCount() {
i=i+1;
postMessage(i);
setTimeout("timedCount()", 500);
}
timedCount();
网友评论