socket.io开发答题游戏clearTimeout无法终止定时器问题求解
问题根本原因
gameTimer 是定义在每个socket连接回调内的局部变量,每个连接的玩家都有自己独立的gameTimer变量,而定时器本身只有房主的socket会创建:你代码里启动setTimeout的两处逻辑(Start Game Countdown事件、Find Host事件)都只有房主身份才会执行,普通玩家的gameTimer自始至终都是null。
当房间内所有玩家答完题触发清定时器逻辑时,要是触发这个逻辑的是普通玩家,你清的是当前普通玩家自己的空gameTimer,根本碰不到房主那边真正运行的定时器,自然无法停止。
修复方案
把定时器从socket维度存储改为房间维度存储即可,具体修改步骤:
- 全局新增一个房间定时器映射表,用来存储每个房间对应的定时器ID:
// 放在io.on('connection')外面全局声明 const roomTimers = new Map()
- 替换所有给
gameTimer赋值的逻辑,改为存入对应房间的映射:
原来的写法:
gameTimer = setTimeout(function () { // 原有业务逻辑 }, 21000)
替换为:
const room = playerData[socket.id].room // 先清掉房间可能存在的旧定时器,避免重复创建 const oldTimer = roomTimers.get(room) if (oldTimer) clearTimeout(oldTimer) roomTimers.set(room, setTimeout(function () { // 原有业务逻辑保持不变 // 定时器执行完后删除映射释放内存 roomTimers.delete(room) }, 21000))
- 替换所有
clearTimeout(gameTimer)的逻辑:
原来的写法:
clearTimeout(gameTimer)
替换为:
const room = playerData[socket.id].room const timer = roomTimers.get(room) if (timer) { clearTimeout(timer) roomTimers.delete(room) }
- 额外补充:在房间销毁(比如房主离开、游戏结束)的逻辑里也加上对应房间定时器的清理操作,避免内存泄漏。
内容的提问来源于stack exchange,提问作者YawZing6
相关产品推荐
相关产品推荐

