了解 web worker

259 阅读2分钟
  1. 什么是 Web Worker?

web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面

Web Worker 有以下几个使用注意点:

(1)同源限制

分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源

(2)DOM 限制

Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象

(3)通信联系

Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成

(4)脚本限制

Worker 可以使用 XMLHttpRequest 对象发出 AJAX 请求

(5)文件限制

Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

  1. Web Workers 用法和API
    (1)主线程
    a. 主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程。Worker()构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务
var worker = new Worker('work.js');

b. 主线程调用worker.postMessage()方法,向 Worker 发消息

worker.postMessage('Hello World');

c. 主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息

worker.onmessage = function (event) {
  console.log('Received message ' + event.data);
}

d. 终止 Web Worker

worker.terminate();

(2)worker 线程
werker线程内部,self代表子线程的全局对象, self也可以省略 a. Worker 线程内部可以通过message事件来监听主线程传过来的消息

//写法一
self.addEventListener('message', function (e) {
 console.log(e.data);
}, false);
//写法二
addEventListener('message', function (e) {
  console.log(e.data);
}, false);

b. Worker 线程内部可以通过postMessage()方法向主线程发送消息

//写法一
postMessage('message from worker');
//写法二
self.postMessage('message from worker');

c. 关闭Worker线程

self.close();
  1. 完整demo
//index.html文件内容
<!DOCTYPE html>
<html>
	<body>
		<p>Count numbers: <output id="result"></output></p>
		<button onclick="startWorker()">Start Worker</button>
		<button onclick="stopWorker()">Stop Worker</button>
		<img src="img/409c81b7.repulims_logo2.png"/>
		<br /><br />

		<script>
			var w;
			function startWorker() {
				if(typeof(Worker) !== "undefined") {
					if(typeof(w) == "undefined") {
					   //新建一个 Worker 线程
						w = new Worker("demo_workers.js");
					}
					w.postMessage('Hello World');
					w.onmessage = function(event) {
						document.getElementById("result").innerHTML = event.data;
					};
				} else {
					document.getElementById("result").innerHTML = "Sorry, your browser"

				}
			}
			function doSomething() {
			  // 执行任务
			  worker.postMessage('Work done!');
			}
			function stopWorker() {
				w.terminate();
			}
		</script>
	</body>
</html>

//demo_workers.js 文件内容
var i = 0;
function timedCount() {
	i = i + 1;
	postMessage(i);
	setTimeout("timedCount()", 500);
}
timedCount();