在 javascript 中,web worker 无法直接传递 set 对象,因为 set 不是结构化克隆算法(structured clone algorithm)支持的类型。要传递 set,必须将其转换为数组(array),通过 postmessage() 发送,并在接收端重新实例化为 set。

主线程如何序列化 Set 并发送给 Worker
主线程需要调用 set.values() 获取迭代器,并将其转换为数组,然后使用 worker.postMessage(array) 发送。这样做是因为结构化克隆算法支持数组,但不支持 Set 的引用或内部结构。发送后,Worker 收到的是一个普通数组,其中包含 Set 中的所有唯一值。
const worker = new Worker('worker.js');
// 创建 Set
const mySet = new Set([1, 2, 3]);
// 转换为数组并发送
worker.postMessage(Array.from(mySet));
// 或者直接使用 spread 语法
// worker.postMessage([...mySet]);
预期结果:Worker 接收到一个数组 [1, 2, 3],而不是 Set 对象。
Worker 如何接收数组并还原为 Set
Worker 在 onmessage 事件中接收到数据后,需要使用 new Set(data) 将数组转换回 Set。这样可以在 Worker 内部恢复 Set 的唯一性特性,以便进行后续操作。这种转换是双向的,主线程和 Worker 都可以采用相同的模式。
// worker.js
self.onmessage = function(e) {
const receivedArray = e.data;
// 将数组还原为 Set
const restoredSet = new Set(receivedArray);
console.log(restoredSet); // Set(3) {1, 2, 3}
console.log(typeof restoredSet); // 'object'
console.log(restoredSet instanceof Set); // true
// 可以继续对 restoredSet 进行操作
restoredSet.add(4);
self.postMessage([...restoredSet]);
};
预期结果:Worker 内部成功创建一个包含 1, 2, 3, 4 的新 Set,并通过 postMessage 将转换后的数组发回主线程。
基于 Array.from() 转换的具体行为与限制
使用 Array.from(set) 或展开运算符 [...set] 时,Set 中的元素会按插入顺序排列。如果 Set 中包含复杂对象,这些对象会被深拷贝,但函数、DOM 节点等不可克隆的类型会导致错误。此外,Set 的空值处理遵循标准规则:空 Set 转换为空数组 [],而 undefined 或 null 作为元素会被正常保留在数组中,但在还原为 Set 时,它们被视为有效值。
// 测试边界情况 const emptySet = new Set(); console.log(Array.from(emptySet)); // [] const setWithNull = new Set([null, undefined, 0]); console.log(Array.from(setWithNull)); // [null, undefined, 0] const restoredFromNull = new Set([null, undefined, 0]); console.log(restoredFromNull.has(null)); // true console.log(restoredFromNull.has(undefined)); // true console.log(restoredFromNull.has(0)); // true
预期结果:空 Set 转换为空数组;包含 null、undefined 和 0 的 Set 正确保留所有元素,还原后仍能通过 has() 方法验证。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











