长时间运行的JS进程会导致浏览器冻结用户界面,让人感觉屏幕"冻结"了。 Web Workers规范通过让JS在后台运行解决了这个问题。
浏览器实现 Web Workers规范的方式有很多种。可以使用 线程、后台进程、运行在其它处理器核心上的进程,等等。
具体的实现细节并没有那么重要,重要的是开发人员可以放心地运行JS,而不必担心会影响用户体验。
支持Web Workers的浏览器: IE10+ 、 Firefox 3.5+ 、Safari4+ 、 Opera 10.6+ 、Chrome 和 iOS版本的Safari。
1. 使用Workers
- 创建一个新的 Web Workers : 实例化一个Worker对象并传入要执行的JS文件名。
var worker = new Worker( "main.js" );
此代码会导致浏览器下载 main.js文件,但只有 Worker接收到消息才会实际执行文件中的代码。
-
使用 postMessage()方法给 Worker传递消息。
worker.postMessage( "Hello Word !" ); worker.postMessage( { type: "command", message: " start !" } );
postMessage()方法接收参数: 任何能够被序列化的值 , 也可以是 一个对象参数。
一般来说, 可以序列化为JSON结构的任何值都可以作为参数传递给 postMessage()。即: 传入的值是被复制到worker中的,而不是直接传过去的。
- Worker 通过 message 和 error事件 与 页面通信。
message事件中, event.data属性中保存着 来自Worker的数据。Worker返回的数据也可以是 任何能够被序列化的值。
worker.onmessage= function( event) {
var data = event.data;
// 对数据进行处理
}
Worker不能完成给定的任务的时候,会触发error事件。即: Worker 内部的JS在执行的过程中只要遇到错误,就会触发 error事件。
发生 error事件时, 时间对象 包含3个属性: filename(发生错误的文件名) 、lineno (代码行号)、 message(完整的错误消息)。
worker. onerror = function( event ){
console.log( "Error:" + event.filename + "(" + event.lineno + "):" + event.message );
}
为防止Worker在发生错误时,悄无声息的失败,最好始终都使用 onerror事件处理程序。
- 停止Worker的工作 : terminate() 方法。
worker.terminate(); // 立即停止worker的工作, 后续所有过程都不会再发生。
2. Worker全局作用域
重点: Web Worker所执行的JS代码 完全在另一个作用域中, 与当前网页中的代码不共享作用域。
在 Web Worker中,有: 一个全局对象 worker 、其他对象 、 方法。
注意: Web Worker中的代码不能访问DOM, 也无法 通过任何方式影响页面的外观。
在这个特殊的全局作用域中, this 和self 引用的都是 worker对象。