JavaScript实现waitFor函数时如何在resolve后正确清除setTimeout计时器
waitFor通用等待函数问题修复方案
原代码存在的问题
- 计时器变量混乱:创建计时器时赋值的隐式全局变量
timer和你清除的_timer不是同一个变量,导致resolve时根本没有清除正在运行的计时器,这是你遇到的「等待完整时长才返回」的核心原因 - 通用能力缺失:硬编码依赖全局变量
_connected,和入参method无关联,传入的回调没有实际作用 - 全局污染:
result、timer变量都没有声明,属于隐式全局变量,会污染全局作用域 - 日志硬编码:超时日志写死了30秒,和入参
max没有联动,适配性差
修复后代码
function waitForGeneric(method, max) { const start = Date.now(); // 计时器变量放在当前函数作用域内,多次调用互不干扰 let timer = null; return new Promise((resolve, reject) => { function check() { // 由传入的method返回判断结果,实现通用能力 const result = method(); if (result) { console.log('connected to server[connection status]: ' + result); // 成功时立即清除计时器终止后续轮询 clearTimeout(timer); resolve(result); } else { if (Date.now() - start > max) { console.log(`waited for ${max / 1000} seconds for connection[connection status]: ` + result); // 超时也清除计时器,避免残留 clearTimeout(timer); reject(new Error('wait for condition timeout')); } else { timer = setTimeout(check, 1000); } } } check(); }); }
调用示例
你原来判断_connected的场景可以这么调用,其他等待逻辑只需要修改传入的回调即可:
waitForGeneric(() => { // 回调返回布尔值,代表是否满足等待结束条件 return window._connected; }, 30000).then(() => { // 满足条件后立即执行,不需要等到最大时长 console.log('连接成功'); }).catch(err => { console.log('等待超时', err); });
内容的提问来源于stack exchange,提问作者SoftwareDveloper
相关产品推荐
相关产品推荐

