JS循环代码运行时跳过偶数计数,问题出在什么地方?
问题根因
你的代码中全局变量i在单次循环逻辑里执行了两次后置自增操作,导致每次完整执行一次myLoop流程后i的步长为2,自然会跳过所有偶数:
- 第一次自增出现在
setTimeout的第二个参数(延迟时长)的位置,调用setTimeout时就会立即执行,自增后的值不会被打印到日志中 - 第二次自增出现在
setTimeout的回调函数的打印逻辑里,自增前的值会作为计数输出
执行流程验证
我们可以拆解初始几次调用的逻辑直观验证问题:
- 初始
i = 0,首次调用myLoop,执行setTimeout时延迟参数取i++的返回值0,执行后i = 1 - 延迟结束触发回调,打印语句取
i++的返回值1输出,执行后i = 2 - 判断
i < 20成立,再次调用myLoop,setTimeout延迟参数取i++的返回值2,执行后i = 3 - 回调触发后打印取
i++的返回值3输出,执行后i = 4
以此类推,最终输出的计数全为奇数,所有偶数都被跳过。
修复方案
只需保证单次循环流程里i只自增一次即可,推荐修改方案如下,去掉延迟参数位置的自增操作:
var i = 0; function myLoop() { setTimeout(function() { console.log(Date() + ' and count is ' + i++); if (i < 20) { myLoop(); } }, i) // 仅使用当前i值作为延迟时长,不做自增 } myLoop()
如果需要保持延迟时长和计数同步递增,该修改方案也能满足需求,每次循环的延迟时长和输出的计数一致。
内容的提问来源于stack exchange,提问作者FooDue
相关产品推荐
相关产品推荐

