readyState值为3表示连接已彻底关闭或从未成功打开;0为CONNECTING(正在连接)、1为OPEN(已建立可通信)、2为CLOSING(关闭中)、3为CLOSED(已关闭/不可用)。

readyState 的四个值分别代表什么状态
readyState 是 WebSocket 实例上的只读属性,返回一个数字,对应四种连接状态。它不是布尔值,不能直接 if (ws.readyState) 判断“是否就绪”——这是最常踩的坑。
实际取值和含义如下:
-
0:CONNECTING,正在连接中(包括 DNS、TCP 握手、WebSocket 升级请求阶段) -
1:OPEN,连接已建立,可以收发消息 -
2:CLOSING,关闭流程已启动(本地或远端调用了close(),但尚未完全断开) -
3:CLOSED,连接已彻底关闭(或从未成功打开过)
只有 ws.readyState === 1 才表示真正可通信。用 === 0 或 == 1 都可能出错——前者漏掉重连时的瞬态,后者在旧版 Safari 中曾有类型转换问题。
为什么不能在 new WebSocket() 后立刻检查 readyState
WebSocket 构造函数是异步发起连接的,new WebSocket(url) 立即返回实例,此时 readyState 通常是 0,但连接远未完成。直接轮询 readyState 或用 setTimeout 等固定时间点检查,既不可靠也不高效。
立即学习“前端免费学习笔记(深入)”;
正确做法是依赖事件驱动:
- 监听
open事件:触发时readyState必为1,且连接已就绪 - 监听
error事件:可能发生在CONNECTING阶段,此时readyState仍为0或已退为0 - 避免在
open外部做send(),否则会抛出InvalidStateError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state
示例片段:
const ws = new WebSocket('wss://echo.websocket.org');
ws.onopen = () => {
console.log('✅ 已就绪,readyState =', ws.readyState); // 总是 1
ws.send('hello');
};
ws.onerror = (e) => {
console.log('❌ 连接失败,当前 readyState =', ws.readyState); // 通常为 0
};
重连逻辑里 readyState 的典型误用
实现自动重连时,常见错误是只看 readyState !== 1 就立即重连——这会导致在 CLOSING(2)状态下重复新建连接,或在 CLOSED(3)后没清空定时器引发内存泄漏。
安全的重连判断应组合状态与事件:
- 仅在
onclose或onerror触发后才考虑重连 - 重连前先检查
ws.readyState === WebSocket.CLOSED(即3),避免对仍在CLOSING的实例重复操作 - 创建新 WebSocket 前,显式设
ws = null,防止旧实例残留监听器干扰
注意:WebSocket.CONNECTING 等常量在部分老环境(如 Android 4.4 WebView)不支持,建议直接用数字或自行定义常量。
readyState 在页面卸载或标签页休眠时的行为
当用户切换标签页、最小化浏览器或系统进入休眠,WebSocket 连接可能被浏览器静默中断,但 readyState 不会自动变为 3,仍保持 1。此时调用 send() 会失败,但不会立刻报错——直到下一次心跳或发送超时后才触发 error 或 close。
这意味着仅靠 readyState === 1 无法保证“此刻能通信”。生产环境必须配合心跳机制(如每 30s send() 一个 ping 消息,并监听响应)来探测真实连通性。
另外,beforeunload 或 pagehide 事件中调用 ws.close() 是良好实践,但要注意:如果此时 readyState 已是 0 或 3,调用 close() 无副作用;若为 1,则会触发 CLOSING → CLOSED 流程。



















