我已经讨论过这个问题的版本,我认为这是独一无二的。为什么延迟为0仍会导致以下行为。
for(var i = 0; i <3; i ++) {
console.log(i, 'started');
setTimeout(()=> {
console.log(i);
},0)
console.log(i, 'done');
}
console.log('loop over');
// 0 started
// 0 done
// 1 started
// 1 done
// 2 started
// 2 done
// loop over
// 3 3 3
到目前为止,我知道认为:
引用MDN关于堆栈上的setTimeouts位置:
这是因为即使setTimeout被延迟调用了 零,它被放置在队列中并计划在下一个队列中运行 机会;不是马上。当前执行的代码必须完成 在执行队列上的函数之前,由此产生 执行顺序可能不如预期。
我是否正确说for-loop和任何同步代码放在 setTimeout之前的调用堆栈上,即使你将延迟设置为0,setTimeout也总是在for之后运行-loop已经完成了?否则,为什么延迟为0仍会导致上述行为?
谢谢!
编辑:
在开始正确的方向后,我找到了一些视频和一个很好的小工具,向您展示事件循环以及它与此示例代码的关系。这是JS运行时模拟器:loupe
答案 0 :(得分:2)
JavaScript,无论是在浏览器中还是在服务器上,都作为事件循环运行。运行时不断轮询事件。事件包括用户操作(例如,点击了DOM元素x),I / O(数据从I / O或ajax调用返回)和计时器事件(在这种情况下)。 {0}只需添加一个事件循环处理的事件,至少经过0毫秒。它将始终在处理完当前事件后执行。
答案 1 :(得分:0)
我说for-loop和任何同步代码都是正确的 在setTimeout
之前的调用堆栈上
要迂腐,setTimeout()本身会被同步调用,并在console.log(i, 'started');
之后立即放在callstack上。它是settimeout 回调(在您的情况下为console.log(i)
),它被排队并异步调用。