关于Web Worker
Web Worker
由于JavaScript是单线程模型,即所有的任务都在一个线程上完成。显而易见,单线程会给后续发展带来较大的限制。而Web Worker就是为JavaScript提供一个多线程环境,允许JavaScript主线程创建Worker线程(子线程)。
在主线程运行的同时,Worker线程也在执行任务,互不干扰。当Worker线程完成任务时,Worker线程再将数据通过消息通信返回给主线程。
Web Worker的使用
主线程中创建Worker线程
用new操作符 + Worker()构造函数,从而创建一个新的Worker线程。
var worker = new Worker('file.js');
注意:Worker()构造函数的参数是一个脚本文件,必须来源于网络(Worker不能读取本地文件)。该文件就是Worker线程要执行的任务。
主线程给Worker线程通信
在主线程中创建好Worker线程之后,主线程需要给Worker线程发送消息,告诉Worker线程可以执行了,Worker线程才会执行下载的脚本文件。也就是说,即使创建了Worker线程且下载好了任务文件,但是Worker线程没有得到主线程的“命令”,它也是不会执行任务的。
通过postMessage(),主线程给Worker线程通信,“通知”Worker线程可以开始了。
worker.postMessage("start your job now !");
postMessage()可以接收对象参数。故也可以写成下面例子所示:
worker.postMessage({
type:"command",
message:"start your job now !"
});
主线程接收Worker线程的消息
主线程通过postMessage(),可以给Worker线程发送消息。同时,主线程通过wx.onmessage指定监听函数,接收Worker子线程发回来的消息。
//主线程用onmessage监听Worker子线程发回的消息
worker.onmessage = function(event){
var data = event.data;
console.log("Data from Worker is :" + data );
doSomething();
}
function doSometiong(){
worker.postMessage("Done Well!"); //主线程再次发消息给Worker线程
}
主线程接收Worker线程发生错误的消息
主线程除了用worker.onmessage监听Worker线程发回的消息,还需要监听一个比较特殊的信息:错误信息。也就是说当Worker因某种原因不能完成主线程派给它的任务,那么主线程应该知道Worker线程无法完成这个任务。
通过worker.onerror去监听Worker的error事件。
当发生error事件时,事件对象有三个属性,filename,lineno和message。
- event.filename : 发生错误事件的文件名
- event.lineno:出错代码行号
- event.message:完整的出错信息
worker.onerror = function(event){
console.log("Error file is :" + event.filename )
}
主线程停止Worker线程的工作
只需调用worker.terminate();就可以停止Worker线程的工作。
worker.terminate();
Worker线程接收来自主线程的消息
主线程可以通过worker.postMessage(),将消息传递给子线程Worker线程。那在Worker线程中,就会触发messge事件。为了处理来自主线程的信息,则需要创建一个onmessage去监听信息。
self.onmessage = function(event){
var data = event.data;
// doSomething
}
除了用onmessage去指定监听函数,也可以通过addEventListener()来指定监听函数,具体代码如下:
self.addEventListener('message',function(e){
//doSomething;
},false)
//或者
this.addEventListener('message',function(e){
//doSomething
},false)
//也可以
addEventListener('message',function(e){
//doSomething
},false)
因为在Worker线程中,self和this都是指向Worker子线程自身,也就是全局对象。所以第三种不写self和this也是可以的。
Worker线程给主线程发送消息
Worker线程也需要向主线程发送消息,用self.postMessage()即可
self.onmessage = function(event){
var data = event.data;
self.postMessage("Already Started!");
// doSomething
}
Worker线程自我结束
在Worker线程中,可以调用self.close()去主动停止工作。
self.close();
Worker线程中加载其它脚本
Worker线程中,可以使用importScripts()方法去加载一个或多个脚本,如:
importScripts("file.js"); //加载一个
importScripts("file1.js","file2.js"); //加载多个
注意:
- 只有所有脚本加载并执行后,才会执行importScripts();
- 加载的多个脚本按顺序执行。就算file2.js先下载完,也是按先后顺序先执行file1.js,再执行file2.js