这是我现在正在使用的代码:
setTimeout(() => console.log('first'), 2000);
for (let i = 0; i < 5000; i++) {
console.log("printing...")
}
setTimeout(() => console.log('second'), 1000);
setTimeout
马上开始倒计时)setTimeout
将执行并启动 2000 毫秒的计时器。但是,由于 setTimeout
回调是异步运行的,因此我们必须跳过它并等待完整的调用堆栈完成,然后再遍历回调队列。for
循环。在我的计算机上,整个 for
循环大约需要 20 秒才能完成运行。进入 for
循环大约几秒钟后,第一个 setTimeout
现在应该用它的计时器完成。setTimeout
将执行并启动计时器。和第一步类似setTimeout
应该先完成延迟,尽管延迟较高,所以它应该打印 "first"
然后 "second"
printing...
/* Lots of "printing..." strings */
printing...
second
first
似乎第二个
setTimeout
仍然先运行。在这种情况下,这是否意味着 setTimeout
倒计时仅在运行最初几行代码后才开始?我在 Firefox 和 Chrome 上测试了这段代码,它们似乎具有相同的行为。
第一次设置超时(延迟2秒):
第一个setTimeout被安排在延迟2000毫秒(2秒)后执行函数() => console.log('first')。 在等待超时的同时,执行 for 循环,向控制台打印“printing...”5000 次。
控制台日志“正在打印...”(5000次):
for循环同步运行,向控制台打印“printing...”5000次。这发生没有任何延迟,因为它是主执行线程的一部分。
第二次setTimeout(1秒延迟):
for循环完成后,第二个setTimeout被安排在延迟1000毫秒(1秒)后执行函数() => console.log('second')。
控制台“首先”记录(脚本启动后 2 秒):
最后,在最初的 2 秒延迟之后,第一个 setTimeout 函数执行,并将“first”记录到控制台。
控制台日志“秒”(脚本启动后 3 秒):
额外的 1 秒延迟后(从脚本开始总共 3 秒),第二个 setTimeout 函数执行,将“秒”记录到控制台。
请记住,setTimeout 函数是异步的,它们不会阻塞主线程的执行。另一方面,for 循环同步运行,并且可能会阻塞线程直到完成。