浅谈HTML5 Web Worker

浏览器中的Web Worker

背景介绍

咱们都知道JavaScript这个语言在执行的时候是采用单线程进行执行的,也就是说在同一时间只能作一件事,这也和这门语言有很大的关系,采用同步执行的方式进行运行,若是出现阻塞,那么后面的代码将不会执行,HTML5则提出了web Worker标准,表示JavaScript容许有多个线程,可是子线程彻底受主线程的控制,子线程不能操做DOM,只有主线程能够操做DOM,因此以主线程为主的单线程执行原理成了JavaScript这门语言的核心。javascript

进程与线程的区别

根本区别:进程是操做系统资源分配的基本单位,而线程是任务调度和执行的基本单位。
在操做系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行。java

兼容性

clipboard.png

web worker是什么?

简单来讲,其实就是在Javascript单线程执行的基础上,开启一个子线程,进行程序处理,而不影响主线程的执行,当子线程执行完毕以后再回到主线程上,在这个过程当中并不影响主线程的执行过程。
举个栗子
clipboard.png
传统状况下,执行下面的代码后,整个页面都会被冻结,因为javascript是单线程处理,以下代码已经彻底组塞了后续的执行web

while(1){}

若是换一种方式,咱们经过开启一个新的线程来执行这段代码,将他放在一个单独的worker.js文件中,在主线程执行如下代码,则能够避免这种状况。数据库

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

Web Worker的用法

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

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做用域

当咱们建立一个新的worker时,该代码会运行在一个全新的javascript的环境中(WorkerGlobalScope)运行,是彻底和建立worker的脚本隔离,这时咱们能够吧建立新worker的脚本叫作主线程,而被建立的新的worker叫作子线程。
WorkerGlobalScope是worker的全局对象,因此它包含全部核心javascript全局对象拥有的属性如JSON等,window的一些属性,也拥有相似于XMLHttpRequest()等。
可是咱们所开启的新的worker也就是子线程,并不支持操做页面的DOM。

线程间的通信是传值而不是传地址

主线程与子线程数据通讯方式有多种,通讯内容,能够是文本,也能够是对象。须要注意的是,这种通讯是拷贝关系,便是传值而不是地址,子线程对通讯内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通讯内容串行化,而后把串行化后的字符串发给子线程,后者再将它还原。

JavaScript中的数据类型存放原理以及传递规则

clipboard.png

共享线程(SharedWorker)

共享线程是为了不线程的重复建立和销毁过程,下降了系统性能的消耗,
共享线程SharedWorker能够同时有多个页面的线程连接。
使用SharedWorker建立共享线程,也须要提供一个javascript脚本文件的URL地址或Blob,该脚本文件中包含了咱们在线程中须要执行的代码,以下:

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

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

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

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

worker.port.postMessage(msg);

运行原理

生命周期

①当一个web worker的文档列表不为空的时候,这个web worker会被称之为许可线程。
②当一个web worker的文档列表中的任何一个对象都是处于彻底活动状态的时候,这个web worker会被称之为须要激活线程。
③当一个web worker是许可线程而且拥有计数器或者拥有数据库事务或者拥有网络链接或者它的web worker列表不为空的时候,这个web worker会被称之为受保护的线程。
④当一个web worker是一个非须要激活线程同时又是一个许可线程的时候,这个web worker会被称之为可挂起线程。

以webKit为例加载并执行worker的过程

clipboard.png

应用

能够作什么:

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

不能够作什么:

1.不能跨域加载JS2.worker内代码不能访问DOM3.各个浏览器对Worker的实现不大一致,例如FF里容许worker中建立新的worker,而Chrome中就不行4.不是每一个浏览器都支持这个新特性

相关文章
相关标签/搜索