JavaScript中for循环如何同时使用timeout与break?代码异常求解决方案
问题原因
你原来的代码没有生效,本质是JavaScript的事件循环机制导致的:
- for循环是同步执行代码,会在主线程一口气跑完所有4次判断,不会等待setTimeout的异步逻辑执行
- 你写的4个setTimeout会被同时推入异步任务队列,几乎在1秒后一起触发,完全达不到间隔1秒检测一次的效果
正确实现方案1:async/await 实现(推荐)
这种写法逻辑和普通循环一致,可读性最高:
// 封装延时工具函数 const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms)) // 异步检测逻辑,maxRetry为最大重试次数,默认4次 async function checkSocketConnection(maxRetry = 4) { for (let i = 0; i < maxRetry; i++) { if (socket.isConnected()) { connectCall([]) return // 连接成功直接结束函数,等价于原逻辑的break } // 未连接则等待1秒再进入下一次循环 await wait(1000) console.log("Call-1: 第" + (i+1) + "次重连检测") } // 此处可添加超出最大重试次数的兜底逻辑 console.log("重试" + maxRetry + "次后仍未连接socket") } // 启动检测 checkSocketConnection()
正确实现方案2:递归 setTimeout 实现
如果运行环境不支持async/await,可以用递归方式实现:
let retryCount = 0 const maxRetry = 4 function checkSocket() { if (socket.isConnected()) { connectCall([]) return } retryCount++ if (retryCount >= maxRetry) { console.log("重试次数已达上限,连接失败") return } // 未连接则1秒后再次调用自身检测 setTimeout(checkSocket, 1000) } // 启动第一次检测 checkSocket()
注意事项
- 不要用同步while循环实现,同步while会阻塞主线程,导致整个程序/页面卡住,连socket的状态更新都会被阻塞,完全无法实现检测效果
- 不推荐使用setInterval实现,因为如果某次检测逻辑执行时间超过间隔,会出现多次检测重叠执行的问题
内容的提问来源于stack exchange,提问作者kevin ladani
相关产品推荐
相关产品推荐

