Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务被 Worker 线程负担了,主线程(通常负责 UI 交互)就不会被阻塞。
主线程代码
<template>
<div>
<p>计数: {{ count }}</p>
<button @click="runOnWebWorker">子线程计数</button>
<button @click="runOnMainThread">主线程计数</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
let worker: Worker | null = null
if (typeof Worker !== 'undefined') {
// 初始化worker线程
worker = new Worker(new URL('./worker.ts', import.meta.url))
// 接收来自worker线程的消息
worker.onmessage = (event) => {
count.value = event.data.payload
}
} else {
alert('抱歉,你的浏览器不支持 Web Workers...')
}
function runOnWebWorker() {
worker?.postMessage(40)
}
function runOnMainThread() {
// 计算斐波那契数列的第 n 项
function fibonacci(n: number): number {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
count.value = fibonacci(40)
}
</script>
- Worker.onerror:指定 error 事件的监听函数。
- Worker.onmessage:指定 message 事件的监听函数,发送过来的数据在
Event.data属性中。 - Worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。
- Worker.postMessage():向 Worker 线程发送消息。
- Worker.terminate():立即终止 Worker 线程。
worker.ts 文件代码
onmessage = function (event) {
const result = fibonacci(event.data)
postMessage({ type: '任务完成', payload: result })
}
// 计算斐波那契数列的第 n 项
function fibonacci(n: number): number {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
- self.name: Worker 的名字。该属性只读,由构造函数指定。
- self.importScripts():加载 JS 脚本。
- self.onmessage:指定
message事件的监听函数。 - self.onmessageerror:指定
messageerror事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。 - self.postMessage():向产生这个 Worker 线程发送消息。
- self.close():关闭 Worker 线程。相当于
worker.terminate()
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。