在 Vue 中使用 Web Worker
使用 Comlink 构建带类型的 Web Worker API、分担繁重计算,以及跟踪响应式进度
在 Vue 中使用 Web Worker 是 CoddyKit 上的免费 Vue Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Vue Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Vue Academy 课程共包含 4 节课。
为什么使用 Web Worker
JavaScript 在与渲染共享的单一主线程上运行。繁重的计算会冻结界面。Web Worker 在独立线程上运行代码,从而让 Vue 应用保持响应。
创建 Worker
从模块文件实例化一个 Worker。Vite 支持 { type: "module" } 选项,并会正确打包该 Worker。
const worker = new Worker(
new URL("./worker.js", import.meta.url),
{ type: "module" }
);Worker 文件
Worker 拥有自己的全局作用域,无法访问 DOM。它会监听消息,并将结果发回。
// worker.js
self.onmessage = (e) => {
const result = heavyCompute(e.data);
self.postMessage(result);
};使用 postMessage 发送数据
在主线程中,调用 postMessage 并传入数据负载。数据会以结构化克隆的方式跨越线程边界。
worker.postMessage({ numbers: [1, 2, 3] });接收结果
使用 onmessage 处理 Worker 的回复。事件的 data 属性保存着发送的值。
worker.onmessage = (e) => {
console.log("result", e.data);
};更新响应式引用
在处理函数中,将结果写入响应式引用,这样模板就会自动更新。
import { ref } from "vue";
const result = ref(null);
worker.onmessage = (e) => {
result.value = e.data;
};在组合式函数中接入
将 Worker 封装在组合式函数中,以便复用和清理。组件卸载时终止 Worker,从而释放线程。
import { ref, onUnmounted } from "vue";
export function useWorker() {
const worker = new Worker(
new URL("./worker.js", import.meta.url),
{ type: "module" }
);
const result = ref(null);
worker.onmessage = (e) => { result.value = e.data; };
onUnmounted(() => worker.terminate());
return { result, run: (d) => worker.postMessage(d) };
}消息协议的麻烦
原始的 postMessage 要求您自行设计消息类型协议,并手动将请求与响应进行匹配。操作较多时,代码会变得冗长。
Comlink 来帮忙
Comlink 封装了消息通道,因此调用 Worker 函数的感觉就像调用本地异步方法一样。请将它与 Worker 一起安装。
npm install comlink从 Worker 暴露 API
在 Worker 中,使用 Comlink.expose 暴露一个由函数组成的对象。
// worker.js
import * as Comlink from "comlink";
const api = {
add: (a, b) => a + b,
process: (data) => heavyCompute(data)
};
Comlink.expose(api);使用 Comlink.wrap 创建类型化代理
在主线程中,Comlink.wrap 会返回一个代理,其方法返回 promise,从而为您提供一个简洁、类型化的 Worker API。
import * as Comlink from "comlink";
const worker = new Worker(
new URL("./worker.js", import.meta.url),
{ type: "module" }
);
const api = Comlink.wrap(worker);
const sum = await api.add(2, 3); // 5快速检查
与原始的 postMessage 相比,Comlink.wrap 提供了什么?
回顾
将繁重的工作转移到使用 new Worker(url, { type: "module" }) 创建的 Web Worker 中。使用 postMessage 发送数据,在 onmessage 中处理回复,并将结果写入响应式引用。将它封装在组件卸载时会终止 Worker 的组合式函数中,并使用 Comlink.wrap 获得简洁、类型化且基于 promise 的代理 API。
常见问题解答
「在 Vue 中使用 Web Worker」课时是免费的吗?
是的 — 「在 Vue 中使用 Web Worker」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Vue Academy 课程的其余内容,请升级到 CoddyKit PRO。 Vue Academy 课程共包含 4 节课。
「在 Vue 中使用 Web Worker」这节课中我会学到什么?
使用 Comlink 构建带类型的 Web Worker API、分担繁重计算,以及跟踪响应式进度 你通过在浏览器中直接运行的动手代码来练习 Vue Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Vue Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Vue Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「在 Vue 中使用 Web Worker」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Vue Academy 课中编写并运行代码吗?
能。每节 Vue Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 v-memo 进行模板记忆化
- 使用 Vue DevTools 性能面板进行性能分析
- 大型列表的虚拟滚动
- 在 Vue 中使用 Web Worker