前端面经 关于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

猜你喜欢

转载自blog.csdn.net/qq_43263320/article/details/114435459