JavaScript for循环异常行为:注释console.log后逻辑不符预期
为什么注释掉console.log会导致阻塞sleep函数失效?
先看正常工作的代码:
function sleep(milliseconds) { var start = new Date().getTime() console.log(`start: ${start}`) for (var i = 0; i < 1e7; i++) { const delta = new Date().getTime() - start console.log(`milliseconds passed: ${delta}`) if (delta > milliseconds) { console.log('exiting') console.log(`final delta: ${delta}`) break } } } sleep(5000) console.log('the end')
这段代码运行时,会先输出start,接着大量打印milliseconds passed,5秒后输出exiting和the end,符合预期。
但注释掉循环内的console.log后,代码行为完全改变:
function sleep(milliseconds) { const start = new Date().getTime() console.log(`start: ${start}`) for (var i = 0; i < 1e7; i++) { const delta = new Date().getTime() - start // console.log(`milliseconds passed: ${delta}`) if (delta > milliseconds) { console.log('exiting') console.log(`final delta: ${delta}`) break } } } sleep(5000) console.log('the end')
运行后只输出start就立刻打印the end,完全没触发退出逻辑。
原因解析
问题核心是循环执行速度的差异:
- 保留
console.log时,每次迭代都要执行控制台输出的IO操作,这是非常耗时的任务。1e7次迭代还没跑完,时间差delta就已经超过5000毫秒,触发break跳出循环,符合预期。 - 去掉
console.log后,循环内只剩获取时间差和条件判断两个轻量操作。现代CPU和JS引擎处理这类计算极快,1e7次迭代可能只需要几毫秒就能完成,远小于设定的5000毫秒。循环直接跑完所有迭代,根本没达到delta > 5000的条件,自然不会执行退出逻辑,直接进入后续代码。
简单说:有log时循环跑得慢,时间先到;没log时循环跑得太快,迭代次数先用完,时间还没到设定值。
内容的提问来源于stack exchange,提问作者Philip
相关产品推荐
相关产品推荐

