结构化克隆由 postmessage 自动触发,与 export 无关;需确保传输数据为支持类型、无函数/dom/循环引用;大数组用 transfer 零拷贝;arkts 中 @sendable 可优化跨线程共享。

直接用 export 无法实现“结构化克隆”导出。结构化克隆是浏览器在 postMessage 通信时自动执行的序列化/反序列化过程,不是由模块导出语法控制的。export 只负责代码层面的模块共享,不参与跨线程数据传递。
真正起作用的是数据本身是否可被结构化克隆
要让业务逻辑的数据能在主线程与 Worker 之间安全、完整地传递,关键不是怎么 export,而是确保你传出去的对象满足结构化克隆的要求:
- 使用支持的类型:ArrayBuffer、TypedArray、DataView、Blob、File、ImageBitmap、ImageData、Map、Set、Date、RegExp、普通对象、数组、字符串、数字、布尔值等
- 避免不可克隆项:函数、class 实例(除非只含可克隆字段)、Error、DOM 节点、Symbol、循环引用、原型方法
- 若需传递复杂状态,建议提前解构为纯数据对象(POJO),例如:
{ id: 1, name: "task", payload: new Uint8Array([1,2,3]) }
Worker 中正确接收和使用导出的逻辑
你可以把业务函数或配置通过 export 暴露,然后在 Worker 内部 import 使用——但这属于代码复用,和结构化克隆无关。真正需要克隆的是运行时传入的参数:
- 主线程调用
worker.postMessage(data)时,data才触发结构化克隆 - Worker 中通过
self.onmessage接收的e.data已是反序列化后的新副本,可直接使用 - 如果业务逻辑封装在导出函数中(如
export function process(input) { ... }),它处理的就是这个已克隆好的input
大数据场景下主动优化克隆开销
当传输 ArrayBuffer 或大文件时,结构化克隆默认会复制整块内存,造成性能瓶颈。这时应改用 Transferable Objects 实现零拷贝:
- 主线程发送时带上
transfer参数:worker.postMessage({ buffer }, [buffer]) - Worker 接收后,
buffer原始引用失效,但可直接读写——这是真正的内存移交,不是克隆 - 注意:Transferable 仅适用于 ArrayBuffer、MessagePort、ImageBitmap 等少数类型,且只能转移一次
@Sendable 类型(ArkTS/ETS 场景)
在 ArkTS(如 DevEco Studio 开发环境)中,@Sendable 是一种编译期标记,用于声明类实例可被安全地跨线程传递。它配合 postMessageWithSharedSendable 接口,实现更高效的对象共享:
- 必须显式标注
@Sendable export class MyTask { ... } - 该类所有字段必须是基础类型、其他 @Sendable 类、ArrayBuffer 等可转移类型
- 运行时不再走完整克隆,而是按规则共享或转移,提升多级 Worker 协作效率










