HTML5 Web Worker用法

Web Worker的用法

简单来说,其实就是在Javascript单线程执行的基础上,开启一个子线程,进行程序处理,而不影响主线程的执行,当子线程执行完毕之后再回到主线程上,在这个过程中并不影响主线程的执行过程。

判断当前浏览器是否支持web worker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (typeof (Worker) != "undefined") { 
//浏览器支持web worker
if (typeof (w) == "undefined") {
//w是未定义的,还没有开始计数
w = new Worker("webworker.js");
//创建一个Worker对象,利用Worker的构造函数
}
//onmessage是Worker对象的properties
w.onmessage = function (event) {
//事件处理函数,用来处理后端的web worker传递过来的消息
// do something
};
}
else {
// 浏览器不支持web worker
// do something
}

API

  • 创建新的Worker

var worker = new Worker("worker.js")

  • 传递参数

worker.postMessage()

  • 接收消息

worker.onMessage = function(msg){}

  • 异常处理

worker.onerror = function(err){}

  • 结束worker

worker.terminate()

  • 载入工具类函数

importScripts()

作用域

创建一个新的worker时,该代码会运行在一个全新的javascript的环境中(WorkerGlobalScope)运行,是完全和创建worker的脚本隔离,这时我们可以把创建新worker的脚本叫做主线程,而被创建的新的worker叫做子线程。

WorkerGlobalScope是worker的全局对象,所以它包含所有核心javascript全局对象拥有的属性如JSON等,window的一些属性,也拥有类似于XMLHttpRequest()等。

但是我们所开启的新的worker也就是子线程,并不支持操作页面的DOM。

共享线程(SharedWorker)

共享线程是为了避免线程的重复创建和销毁过程,降低了系统性能的消耗,共享线程SharedWorker可以同时有多个页面的线程链接。

var worker = new SharedWorker("sharedworker.js");

共享线程也使用了message事件监听线程消息,但使用SharedWorker对象的port属性与线程通信如下:

worker.port.onmessage = function(msg){};

同时我们也可以使用SharedWorker对象的port属性向共享线程发送消息如下:

worker.port.postMessage(msg);

应用

  • 可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信
  • 可以在worker中通过importScripts(url)加载另外的脚本文件
  • 可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()
  • 可以使用XMLHttpRequest来发送请求
  • 可以访问navigator的部分属性

注意事项

  • 不能跨域加载JS
  • worker内代码不能访问DOM
  • 各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行
  • 不是每个浏览器都支持这个新特性