javascript 为什么在condition中使用Date.now()会创建一个无限循环?

vngu2lb8  于 11个月前  发布在  Java
关注(0)|答案(2)|浏览(131)

我想创建一个可以模拟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)
}

mrzz3bfm

mrzz3bfm1#

我想测试一下你收到的评论,说这是一个“console.log”问题-你遇到的问题是因为你的电脑正在努力处理所有这些日志调用。我注解掉了它,只有在循环结束后console.logged:

let a = Date.now() + 5000;
while(Date.now() < a) {
    // console.log(1);
}

console.log('done');

字符串
它似乎工作得很好,日志'完成'后5秒。
编辑。在Pointy的提示下,我接受了在这里放一个免责声明可能是个好主意:没有人应该实现这种循环作为等待的方式。

nom7f22z

nom7f22z2#

实际上,你的代码并没有创建无限循环。它会一直打印1,直到5秒结束。我在本地测试了它。但是打印速度很快,它看起来像无限循环。向下滚动,看到最后打印将停止。你可以通过只给500毫秒来尝试相同的代码。

let a = Date.now() + 500;
while(Date.now() < a) {
    console.log(1);
}
console.log("finished");

字符串
现在来另一个问题,以了解为什么设置工作,你必须了解JavaScript的内部工作。我会推荐这个视频How JavaScript Works 🔥& Execution Context
在JS中,所有将要执行的函数都被推到调用堆栈中执行。在这种情况下,console.log方法在while循环中。
JS引擎也有一个回调队列,它将有回调函数准备执行,并且有一个事件循环,它总是检查调用堆栈是否为空。如果是,它将从回调队列中取出回调函数并将其推送到调用堆栈执行。这里的setTimeout函数有一个回调,一旦计时器到期,这个回调将被推送到回调队列。
你的while循环只是推动console.log一个接一个地执行,它很快就被执行了。但是,一旦回调队列中出现回调,调用堆栈暂时为空,(意味着它已经准备好执行另一个函数),事件循环只是推送回调执行并从队列中删除。这个过程将继续,直到队列中的所有回调都被删除。执行。所以回调在执行时有更高的优先级。你也可以尝试使用多个setTimeout的例子。
希望这对你有帮助。

相关问题