众所周知,Javascript是运行在单线程环境中,也就是说无法同时运行多个脚本。假设用户点击一个按钮,触发了一段用于计算的Javascript代码,那么在这段代码执行完毕之前,页面是无法响应用户操作的。但是,如果将这段代码交给Web Worker去运行的话,那么情况就不一样了:浏览器会在后台启动一个独立的worker线程来专门负责这段代码的运行,因此,页面在这段Javascript代码运行期间依然可以响应用户的其他操作。
Web Worker简介
Web Worker 是HTML5标准的一部分,这一规范定义了一套 API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中。
值得注意的是, Web Worker 规范中定义了两类工作线程,分别是专用线程Dedicated Worker和共享线程 Shared Worker,其中,Dedicated Worker只能为一个页面所使用,而Shared Worker则可以被多个页面所共享。
Web Worker 使用注意如下常见的几点:
同源限制:分配给 Worker线程运行的脚本文件,必须与主线程的脚本文件同源。2. DOM限制:Worker所在的线程它不能操作window,document这样的对象,也就是说worker线程不能操作dom对象,但是worker线程可以操作业务逻辑,然后把操作后的结果返回给主线程,主线程再去做相关的DOM操作。
文件限制:Worker线程无法读取本地文件,也就是说不能打开本机的文件系统(如:file://) 这样的,它所加载的脚本,必须来自网络。
来看下我们的 public/js/main.js 代码如下:
// 加载css样式
require('../styles/main.styl');
import Worker from './test1.worker.js';
// 创建worker实列
var worker = new Worker();
// 向worker线程发送消息
worker.postMessage('主线程向worker线程发送消息');
// 监听worker线程发送回来的消息
worker.onmessage = function(e) {
console.log('监听worker线程发送回来的消息如下所示:')
console.log(e);
};
public/js/test1.worker.js(子线程)的代码如下所示:
// 监听消息
onmessage = function(e) {
console.log('监听到的消息为:' + e.data);
}
const msg = '工作线程向主线程发送消息';
// 发送消息
postMessage(msg);
如上代码,我们首先创建了一个worker实列,如代码:var worker = new Worker(); 然后他就会调用 test1.worker.js 代码,该worker中的代码会首先给主线程发送消息,消息文本为: '工作线程向主线程发送消息'; 然后我们的主线程中会通过 worker.onmessage 事件来监听子线程的消息,因此我们第一次打印出来为如下代码的消息:
worker.onmessage = function(e) { console.log('监听worker线程发送回来的消息如下所示:') console.log(e); };
然后我们的主线程才会向子线程发送消息,如下代码:
// 向worker线程发送消息 worker.postMessage('主线程向worker线程发送消息');
然后 test1.worker.js 代码中的 onmessage 就能监听到消息,如下所示:
// 监听消息 onmessage = function(e) { console.log('监听到的消息为:' + e.data); }
最后就会打印出信息如下:"监听到的消息为:主线程向worker线程发送消息"。