能否用Promise封装SharedWorker?webworker-promise报错求解决方案
问题分析与解决
报错原因
webworker-promise是为普通Worker设计的,普通Worker实例本身自带postMessage方法,但SharedWorker的通信得靠它的port对象完成——你直接把SharedWorker实例传给WebworkerPromise,库内部调用this._worker.postMessage肯定报错,因为SharedWorker本身没这个方法。
手动适配SharedWorker到webworker-promise
自己写个适配层,把postMessage、事件监听这些操作代理到SharedWorker的port上就行:
import WebworkerPromise from 'webworker-promise' const sharedWorker = new SharedWorker('worker.ts'); // 封装符合webworker-promise要求的对象 const adaptedWorker = { postMessage: (data) => sharedWorker.port.postMessage(data), addEventListener: (type, handler) => { if (type === 'message') { sharedWorker.port.addEventListener('message', handler); } }, removeEventListener: (type, handler) => { if (type === 'message') { sharedWorker.port.removeEventListener('message', handler); } }, terminate: () => sharedWorker.port.close() }; // 必须调用start()启动端口通信 sharedWorker.port.start(); const worker = new WebworkerPromise(adaptedWorker);
对应的Worker脚本(worker.ts)也要改成用self.onconnect处理连接:
self.onconnect = (e) => { const port = e.ports[0]; port.onmessage = (msg) => { // 处理消息后返回结果 port.postMessage({ result: `处理了消息:${msg.data}` }); }; port.start(); };
替代库推荐
嫌手动适配麻烦的话,换个原生支持SharedWorker的库更省心:
- comlink:完全基于Promise,对SharedWorker支持友好,写法简洁,不用手动管端口那套。
主线程代码:
Worker端代码:import * as Comlink from 'comlink'; const sharedWorker = new SharedWorker('worker.ts'); const workerApi = Comlink.wrap(sharedWorker.port); // 直接调用Worker里暴露的方法 const result = await workerApi.processData('测试参数');import * as Comlink from 'comlink'; const workerApi = { processData: (param) => { return `处理后的结果:${param}`; } }; self.onconnect = (e) => { const port = e.ports[0]; Comlink.expose(workerApi, port); }; - workerize:主打轻量,虽然默认是普通Worker,但也能通过类似适配的方式支持SharedWorker,同样是Promise风格调用。
内容的提问来源于stack exchange,提问作者BAR
相关产品推荐
相关产品推荐

