我想创建一个可以模拟5秒延迟的循环,但最终创建了一个无限循环。我不明白为什么会这样。
let a = Date.now() + 5000;
while(Date.now() < a) {
console.log(1);
}
字符串
a是一个固定值,Date.now()不是应该在每次迭代后都改变吗?
我也想知道为什么setbacks在循环是无限的时候仍然工作?它不是应该只在当前执行的脚本完成后才被执行吗?既然这个脚本永远不会完成,为什么setbacks仍然被调用?
setTimeout(() => {
alert(2);
}, 2000);
let a = Date.now() + 5000;
while( Date.now() < a ) {
console.log(1)
}
型
2条答案
按热度按时间mrzz3bfm1#
我想测试一下你收到的评论,说这是一个“console.log”问题-你遇到的问题是因为你的电脑正在努力处理所有这些日志调用。我注解掉了它,只有在循环结束后console.logged:
字符串
它似乎工作得很好,日志'完成'后5秒。
编辑。在Pointy的提示下,我接受了在这里放一个免责声明可能是个好主意:没有人应该实现这种循环作为等待的方式。
nom7f22z2#
实际上,你的代码并没有创建无限循环。它会一直打印1,直到5秒结束。我在本地测试了它。但是打印速度很快,它看起来像无限循环。向下滚动,看到最后打印将停止。你可以通过只给500毫秒来尝试相同的代码。
字符串
现在来另一个问题,以了解为什么设置工作,你必须了解JavaScript的内部工作。我会推荐这个视频How JavaScript Works 🔥& Execution Context
在JS中,所有将要执行的函数都被推到调用堆栈中执行。在这种情况下,
console.log
方法在while循环中。JS引擎也有一个回调队列,它将有回调函数准备执行,并且有一个事件循环,它总是检查调用堆栈是否为空。如果是,它将从回调队列中取出回调函数并将其推送到调用堆栈执行。这里的
setTimeout
函数有一个回调,一旦计时器到期,这个回调将被推送到回调队列。你的while循环只是推动
console.log
一个接一个地执行,它很快就被执行了。但是,一旦回调队列中出现回调,调用堆栈暂时为空,(意味着它已经准备好执行另一个函数),事件循环只是推送回调执行并从队列中删除。这个过程将继续,直到队列中的所有回调都被删除。执行。所以回调在执行时有更高的优先级。你也可以尝试使用多个setTimeout
的例子。希望这对你有帮助。