async/await 本身不提供 Web Worker 通信能力,仅是 Promise 的语法糖;真正通信依赖 postMessage/onmessage 的事件驱动机制,并需手动封装为 Promise 以支持 await 调用。

async/await 本身不直接提供 Web Worker 的通信能力,它只是让 Promise 链更简洁;真正实现异步通信的是基于 postMessage 和 onmessage 构建的 Promise 封装层。
async/await 不是通信协议,而是语法糖
Web Worker 的底层通信始终是事件驱动的:主线程发消息、Worker 收到后处理、再回传。这个过程天然是异步的,但原始 API 是回调风格(worker.onmessage = () => {})。async/await 无法绕过这个机制,只能包装它——把每次 postMessage 调用变成一个返回 Promise 的函数,等收到 message 事件时 resolve。
关键点:
- Worker 内部没有
await通信能力,它仍靠self.onmessage接收、self.postMessage发送 - 主线程中所谓“await 调用 Worker”,其实是 await 了一个封装好的 Promise,该 Promise 在监听到
message后才结束 - 一次
postMessage对应一次message响应,不能靠 await 实现“连续流式响应”,需自行设计消息 ID 或 channel 区分请求/响应
如何安全封装 Worker 通信为 Promise
手动封装时要注意避免监听器堆积和响应错乱。推荐做法是为每次调用绑定唯一 listener,并在收到响应后立即移除:
微信小程序 TabBar 图标生成技能,使用 Python PIL 绘制简约几何图标(未选中灰、选中绿),自动写入 app.json 配置。适用于“生成 tabBar 图标”、“底部菜单栏图标”、“tab 图标”等指令。
示例封装函数:
function callWorker(worker, msg) {
return new Promise((resolve, reject) => {
const handler = (event) => {
if (event.data?.id === msg.id) { // 用 id 匹配请求与响应
resolve(event.data.result);
worker.removeEventListener('message', handler);
}
};
worker.addEventListener('message', handler);
worker.postMessage(msg); // 带 id 的消息体:{ id: Date.now(), data: 'xxx' }
});
}
这样可支持并发多次调用,互不干扰。
微信小程序中的差异点
小程序不支持标准 new Worker(),而是用 wx.createWorker(),其 API 设计已内置 Promise 支持:
-
worker.postMessage()返回 Promise(部分基础库版本需确认) - 推荐写法:
await worker.postMessage({ task: 'heavyCalc', payload }) - 注意:仍需在
worker.onMessage中主动调用self.postMessage(),否则 Promise 不会 resolve
别混淆:async/await 不等于多线程
async/await 只改变代码书写方式,不创建新线程;Web Worker 才真正启用独立线程。两者配合的价值在于:
- 主线程保持响应:耗时计算交给 Worker 线程,主线程用 await 等结果,期间仍可处理用户操作
- 逻辑更清晰:比起嵌套
postMessage + onmessage回调,await 让“发任务→等结果”流程一目了然 - 错误可捕获:用 try/catch 包裹 await 调用,比手动监听 error 事件更自然

















