websocket需封装connect()等待open事件,send()不可await,应通过唯一id匹配响应消息并用waitformessage()等待,配合pendingrequests map实现rpc模式。

WebSocket 本身是事件驱动的,不能直接 await ws.send() 或 await ws.receive(),因为浏览器原生 API 没有返回 Promise。但你可以用 Promise 封装关键环节,让“发完等响应”这类逻辑更清晰、可控。
连接建立必须 await
new WebSocket() 立即返回实例,但连接是否就绪需等 open 事件。直接调用 send() 可能失败。
- 封装一个
connect(url)函数,内部创建 WebSocket,监听open→ resolve;监听error或超时(如 5s)→ reject - 连接成功后,记得移除临时绑定的
error监听器,避免内存泄漏 - 调用:
const ws = await connect("wss://api.example.com");
发消息不等于收到响应,别误用 await send()
await ws.send(...) 是无效写法——send() 返回 undefined,且它只表示数据已入缓冲区,不表示服务端已处理或回传。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 真正要等的是服务端返回的特定响应消息,比如
{ id: "req-123", result: ... } - 不要写
await ws.send(msg); const resp = await ws.recv();(recv()不是原生方法) - 正确做法:发完后主动等待匹配 ID 的那条
message,用waitForMessage(ws, predicate)封装
等一条特定消息:用 Promise 包装 onmessage
每次等待都应独立、可取消,避免多个 waitForMessage 互相干扰。
- 函数接收
ws和一个判断逻辑predicate(例如msg.id === myId) - 内部设
isResolved = false,在onmessage中满足条件时resolve(data)并设标志 - 务必加超时保护:
Promise.race([waitPromise, timeoutPromise]) - 消息匹配后,立即移除该次监听,防止后续消息误触发
实现请求-响应模式(RPC 风格)
适合登录、拉数据等“发指令、等结果”的场景,核心是靠唯一 ID 关联请求与响应。
- 维护一个
pendingRequests = new Map(),key 是随机 ID(如crypto.randomUUID()) -
call(method, params)发送前存入pendingRequests.set(id, { resolve, reject }) - 全局
onmessage解析响应,若data.id存在,则调用对应resolve()并从 Map 删除 - 连接关闭时,遍历 Map 对所有 pending 请求
reject(new Error("disconnected")),防止悬空
不复杂但容易忽略:每次 send 前检查 ws.readyState === WebSocket.OPEN,否则抛错;多个并发请求必须靠 ID 隔离,不能共用同一套等待逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










