跳到主要内容

worker技巧

  • 封装一个统一的useWorker的hooks方法

useWorker​

基于vue封装​

js
// useWorker.js
import { ref, onBeforeUnmount } from 'vue';

export function useWorker(
urlOrFactory,
{ autoStart = true, timeout = 0 } = {}
) {
const message = ref(null);
const error = ref(null);
const running = ref(false);
let worker = null;
let timerId = null;

// 创建 Worker:支持 URL 或 Blob
function createWorker() {
if (typeof urlOrFactory === 'function') {
const code = urlOrFactory();
const blob = new Blob([code], { type: 'application/javascript' });
return new Worker(URL.createObjectURL(blob));
} else {
return new Worker(urlOrFactory);
}
}

// 启动 Worker
function start() {
if (worker) return;
worker = createWorker();
running.value = true;

worker.onmessage = (e) => {
message.value = e.data;
// 清除超时
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
};

worker.onerror = (e) => {
error.value = e;
running.value = false;
worker.terminate();
worker = null;
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
};
}

// 发送消息
function post(data, transfer) {
if (!worker) start();
if (timeout > 0) {
timerId = setTimeout(() => {
error.value = new Error('Worker request timed out');
terminate();
}, timeout);
}
// 支持可转移对象数组
if (Array.isArray(transfer)) {
worker.postMessage(data, transfer);
} else {
worker.postMessage(data);
}
}

// 手动终止
function terminate() {
if (worker) {
worker.terminate();
worker = null;
running.value = false;
}
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
}

// 组件卸载时清理
onBeforeUnmount(() => {
terminate();
});

// autoStart 可选
if (autoStart) start();

return { message, error, running, post, terminate };
}