javascript web worker 无法直接传递 class 实例,因为 worker 运行在独立的执行上下文中,内存不共享。正确的做法是将 class 的定义代码作为字符串传递给 worker,并在 worker 内部通过 eval() 或 new function() 重新定义该类,随后实例化并发送数据。

主线程如何发送 Class 定义
主线程需要将 Class 的源码转换为字符串,并通过 postMessage 发送给 Worker。Worker 收到后执行该字符串以重建类结构。

const workerCode = `
class DataProcessor {
constructor(data) {
this.data = data;
}
process() {
return this.data.map(x => x * 2);
}
}
self.onmessage = function(e) {
const { action, payload } = e.data;
if (action === 'init') {
// 假设 payload 是初始数据
const instance = new DataProcessor(payload);
self.postMessage({ type: 'result', value: instance.process() });
}
};
`;
const blob = new Blob([workerCode], { type: 'application/javascript' });
const worker = new Worker(URL.createObjectURL(blob));
worker.onmessage = (e) => {
console.log('Received:', e.data.value); // [2, 4, 6]
};
worker.postMessage({ action: 'init', payload: [1, 2, 3] });
Worker 内部如何处理 Class 实例化
Worker 接收到包含 Class 定义的代码块后,必须立即执行该代码以注册 DataProcessor 类。只有类被定义后,才能创建其实例并调用其方法。此过程确保了 Worker 拥有与主线程逻辑一致的类定义,但拥有独立的内存空间。

// Worker 内部逻辑示意(实际由 Blob 内容执行)
// 1. 定义类
const DataProcessor = class {
constructor(data) { this.data = data; }
process() { return this.data.map(x => x * 2); }
};
// 2. 监听消息
self.onmessage = function(e) {
const msg = e.data;
if (msg.action === 'init') {
// 3. 实例化并处理
const processor = new DataProcessor(msg.payload);
const result = processor.process();
// 4. 发送结果(仅传输数据,非实例)
self.postMessage({ type: 'result', value: result });
}
};
基于 postMessage 传输的数据类型限制
在使用上述模式时,必须注意 postMessage 的序列化机制。Class 实例本身不能被直接跨线程传递,只能传递其序列化的数据副本。这意味着如果 Class 中包含不可序列化的属性(如函数、DOM 引用),这些属性在到达另一端时会丢失。因此,设计用于 Worker 通信的 Class 应仅包含可序列化的数据字段,或者在 Worker 内部完成所有涉及复杂对象的操作,仅返回最终的计算结果。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











