comlink 使 web worker 调用如普通函数般简洁,通过 wrap() 封装 worker、expose() 暴露接口,支持 promise 代理、class 实例绑定、结构化克隆数据传递及 proxy 模式动态属性访问。

Comlink 让 Web Worker 的调用看起来就像调用普通函数一样,自动处理消息传递、Promise 代理和跨线程对象绑定。核心是用 Comlink.wrap() 包装 Worker 实例,再用 Comlink.expose() 暴露 Worker 内的函数或对象。
1. 基础封装:让 Worker 方法像 await 本地函数一样调用
Worker 端(worker.js)只需暴露一个对象,里面放函数或类实例:
// worker.js
import * as Comlink from 'comlink';
<p>const utils = {
async fetchData(url) {
const res = await fetch(url);
return res.json();
},
add(a, b) {
return a + b;
}
};</p><p>Comlink.expose(utils, self); // 暴露给主线程</p>主线程中创建 Worker 并用 Comlink.wrap() 封装,之后就能直接 await:
// main.js
import * as Comlink from 'comlink';
<p>const worker = new Worker('./worker.js', { type: 'module' });
const utils = Comlink.wrap(worker);</p><p>// ✅ 看起来完全同步,实际异步跨线程执行
const data = await utils.fetchData('<a href="https://www.php.cn/link/46b315dd44d174daf5617e22b3ac94ca">https://www.php.cn/link/46b315dd44d174daf5617e22b3ac94ca</a>');
console.log(data);
console.log(utils.add(2, 3)); // 返回 Promise<number></number></p>2. 支持 class 实例与 this 绑定
Worker 中可暴露 class 实例,Comlink 会自动代理方法调用和 this 上下文:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
// worker.js
class Counter {
constructor() {
this.count = 0;
}
increment() {
this.count++;
return this.count;
}
getCount() {
return this.count;
}
}
<p>Comlink.expose(new Counter(), self);</p>主线程中使用时,每次调用都保持同一实例状态(注意:Worker 是单例,所以状态在 Worker 内维持):
const counter = Comlink.wrap(worker); console.log(await counter.increment()); // 1 console.log(await counter.increment()); // 2 console.log(await counter.getCount()); // 2
3. 处理函数参数与返回值的限制
Comlink 默认只支持可结构化克隆(structured clone)的数据,比如普通对象、数组、Date、RegExp 等。不支持函数、Error、Map/Set(除非显式启用 Transferable 支持)。
- 如需传复杂对象(如
Map、Set、ArrayBuffer),需配合Comlink.transfer()或启用proxy模式(见下方) - 若要传递函数回调到 Worker,必须用
Comlink.proxy()包装,否则会被丢弃 - Worker 抛出的错误会自动转为主线程的
Error实例(含 stack),无需手动 catch 转换
4. 进阶:启用 Proxy 模式支持动态属性与嵌套对象
默认 Comlink 对象是“冻结”的(只代理已知方法)。若需要访问任意属性、支持 getter/setter 或嵌套对象响应式访问,启用 { proxy: true }:
// 主线程
const api = Comlink.wrap(worker, { proxy: true });
<p>// 可以这样写(即使 worker 没定义 .users 属性,但返回的是 proxy)
const users = await api.getUsers(); // 返回一个 proxy 对象
console.log(users[0].name); // 自动转发到 Worker 查询</p>⚠️ 注意:proxy 模式有轻微性能开销,且要求 Worker 端返回的对象也支持 Comlink 代理(例如用 Comlink.proxy() 或返回 plain object)。










