/技术
分类:技术最近更新:2026-04-15浏览:1382
JS 是单线程的,也就是任务得一件件的按照顺序处理,前面的任务没有处理完成,后面的只能等着。但是随着科技的发展,现在的计算机都是多核的 CPU,单线程无法发挥计算机的能力。
Web Worker 的作用就是在 JS 主线程上创建一个辅助线程(Worker 线程),将一些任务分配给 Worker 线程运行。两个线程互不干扰,也能相互通信。用户在主线程上进行 UI 交互时,不会卡顿和阻塞。Worker 线程也不会因为主线程交互而被打断。这个和之前的 Service Worker 很类似。
注意,Worker 线程比较耗费资源,不应该过度使用,任务完成后要关闭。同时,Web Worker 有以下几个使用注意点:
document,window,parent 等对象,但可以操作 navigator 和 location 对象alert() 和 confirm() 方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求xx.postMessage 相互通信javascriptvar worker = new Worker('./work.js');
构造函数 Worker 引用的脚本文件 work.js 就是 Worker 线程的执行任务。如果构造函数 Worker 引用的参数路径不对,Worker 会默认失败,Worker 线程将不执行。
javascriptworker.postMessage('Hello World'); worker.postMessage({method: 'echo', args: ['Work']});
主线程通过实例对象 worker 的 postMessage 向 Worker 发消息。postMessage 的参数可以是任意类型。
javascriptworker.onmessage = function (event) { console.log('Received message ' + event.data); doSomething(); } function doSomething() { // 执行任务 worker.postMessage('Work done!'); }
主线程通过调用实例 onmessage 方法监听 Worker 线程发来的消息(event.data)。
javascriptworker.terminate();
javascriptself.addEventListener('message', function (e) { self.postMessage('You said: ' + e.data); }, false);
self 代表 Worker 线程的全局对象,等同下面两种写法:
javascript// 写法一 this.addEventListener('message', function (e) { this.postMessage('You said: ' + e.data); }, false); // 写法二 addEventListener('message', function (e) { postMessage('You said: ' + e.data); }, false);
javascriptself.addEventListener('message', function (e) { var data = e.data; switch (data.cmd) { case 'start': self.postMessage('WORKER STARTED: ' + data.msg); break; case 'stop': self.postMessage('WORKER STOPPED: ' + data.msg); self.close(); // Terminates the worker. break; default: self.postMessage('Unknown command: ' + data.msg); }; }, false);
和主线程方法一样,通过调用 Worker 线程的 postMessage 向主线程发送消息,参数就是发送的数据。
javascriptself.close();
html<script type="text/js-worker"> // worker线程的脚本 addEventListener('message', function () { postMessage('some message'); }, false); </script> <script> // 主线程脚本 var blob = new Blob([document.querySelector('script[type="text/js-worker"]').textContent]); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); worker.onmessage = function (e) { // e.data === 'some message' }; </script>
上面代码中,先将嵌入网页的脚本代码,转成一个二进制对象,然后为这个二进制对象生成 URL,再让 Worker 加载这个 URL。这样就做到了,主线程和 Worker 的代码都在同一个网页上面。
Worker()javascriptvar myWorker = new Worker(jsUrl, options);
主线程全局对象提供了 Worker 构造函数,它接收两个参数,第一个参数是脚本文件的同源网址,该参数必须的,否则会报错;第二个参数是可选的配置对象,它的主要作用是指定 Worker 线程的名称,用来区分多个 Worker 线程。
// 主线程
javascriptvar myWorker = new Worker('worker.js', { name : 'myWorker' });
// Worker 线程
javascriptself.name // myWorker
Worker() 创建的实例对象,提供了以下属性和方法:
error 事件的监听函数message 事件的监听函数,发送过来的数据在 Event.data 属性中messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件Web Worker 有自己的全局对象,不是主线程的 window,而是一个专门为 Worker 定制的全局对象。因此定义在 window 上面的对象和方法不是全部都可以使用。
Worker 线程有一些自己的全局属性和方法:
message 事件的监听函数messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件