Web Worker
- Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。
- 此外,它们可以使用 XMLHttpRequest(尽管 responseXML 和 channel 属性总是为空)或 fetch(没有这些限制)执行 I/O。
- 一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理器(反之亦然)。
创建一个专用 worker
js
// main.js
// 生成一个专用 worker -- 指定一个脚本的 URI 来执行 worker 线程
const worker = new Worker(
'http://localhost:5173/programmer/worker.js',
{type: 'module'}
);
// 1. 监听从 worker 发来的消息两种方法(二选一)
// 使用 addEventListener() 方法
worker.addEventListener("message", (MessageEvent) => {});
// onmessage 事件处理函数
worker.onmessage = (MessageEvent) => {};
/*
2. 使用 postMessage() 方法发送消息
- 第一个参数是要发送到 worker 的数据。该数据可以是任何可以被结构化克隆算法处理的 js 对象
- 第二个参数是可选的、会被转移所有权的可转移对象数组。
*/
const btn = document.getElementById('#btn')
// 按钮点击事件触发时向 worker 发送消息
btn.addEventListener('click', () => {
worker.postMessage([first.value, second.value])
console.log("Message posted to worker");
})
事件处理函数代码作为响应
js
// worker.js
// 模块引入 -- 必须是网络地址且可以跨域
importScripts("http://localhost:5173/programmer/worker2.js")
import {sub} from "http://localhost:5173/programmer/worker3.js"
// onmessage 处理函数允许我们在收到消息时运行一些代码
self.onmessage = (e) => {
const [first, second] = e.data;
// 发送消息 -- 将结果回传给主线程
self.postMessage({add:add(first, second), sub:sub(first, second)});
}
// worker2.js
function add(first, second) {
return first + second;
}
// worker3.js
export default function sub(first, second) {
return first - second;
}
终止 worker
js
// main.js
worker.terminate();
注意事项
- webworker不能使用本地文件,必须是网络上的同源文件。
- webworker不能使用window上的dom操作,也不能获取dom对象,dom相关的东西只有主线程有。只能做一些计算相关的操作。
- 有的东西是无法通过主线程传递个子线程的,比如function、dom节点,一些对象里的特殊设置(freeze,getter,setter这些,所以vue的响应式对象是不能传递的)
- 模块的引入问题(必须是网络地址且可以跨域),如果js文件是esmoudle的话,那么new Worker时需要申明,new Worker(url, {type: 'module'})
常见应用
webworker的常见主要就是耗时的计算
- 随着webgl,canvas等能力的加入,web前端有越来越多的可视化操作。比如在线滤镜,在线绘图,web游戏等等。这些东西都是非常消耗计算的
- 一些后台管理系统也会涉及到一些,最常见的就是一些电子表单。大量的数据大量的计算比如10万条数据导出为excel表格
- 大文件的分片上传下载等等