events loop

html中代码

<div class="po">32wewe</div>

JavaScript代码

var po = document.querySelector('.po')
var op = 0
for (var k = 0; k < 3; k++) {
    setTimeout(function () {
        console.log(k)
    }, 0)
}

var p;
for (var i = 0; i < 999999666; i++) {
    p = i
}
console.log(p)
po.addEventListener('click', function (e) {
    console.log(++op)
})
po.click()
console.log('主线程结束')

如果主线程在执行的时候,我疯狂点击po元素,最后setTimeout永远都是最后显示,即使在这里立即执行click也是,看了别人写的文章关于js的events loop,难道我没理解到其中的深意?上面所说的情况都是在谷歌下测试的

阅读 2.8k
4 个回答

正常情况下的输出应该是

999999665
1
主线程结束
3
3
3

setTimeout的时间参数默认最小值是4ms,而且setTimeout的函数会被推入到事件队列中,等待主线程执行完毕后再加入到执行栈执行。
同样的,click触发的事件也是先加入事件队列,等待主线程内全部执行完毕后再按次序加入执行栈执行。
具体的你还是看这篇文章吧,一句两句讲不清楚。

并不知道你说的 events loop 是什么? 但是就我所知道的知识可以解释你这个情况,

我疯狂点击po元素,最后setTimeout永远都是最后显示

这里要说定时器的工作机制了;

除了主JavaScript 执行进程外,还有一个需要在进程下一次空闲时执行的代码队列;

定时器对队列的工作方式是,当特定时间过去后将代码插入。注意,给队列添加代码并不意味着对它立刻执行,而只能表示它会尽快执行;

如果在这个时间点上,队列中没有其他东西,那么这段代码就会被执行;

在这里,我理解,如果 间隔 = 0 相当于,就相当于,在执行顺序上降低了优先级,因为 setTimeout 让 他的回调等待队列空闲再执行,相当于本来我先运行,现在我等别人运行完了我再运行;不信可以测试下下面代码:

setTimeout('alert(1)',0);
alert(2);
alert(3);

这里会把 alert(1) 放在最后执行,间隔为0相当于降低了执行顺序的优先级;

题主疯狂点击po元素,就是在不断往下一次执行的代码队列里不断添加新的代码,setTimeout 一直要等待空闲,那自然就是最后显示了。红框是 setTimeout

clipboard.png

详情可以戳这里了解:innerHTML 延后执行?

1.p.click是一个同步调用其效果相当于使用p元素执行dispatchEvent发送了一个模拟的鼠标点击动作,而这个动作是同步调用,也就是回去检查是否有对应的事件回调函数绑定到p上,如果有就同步调用
这个你可以通过如下代码验证:

...
    po.addEventListener('click', function (e) {
        console.log(++op);
        console.log("click event listener invoked")
    });

...
po.click();
console.log("after po.click();");

输出:
···
click event listener invoked
after po.click();
···

2.用户操作的事件回调队列执行的优先级要高于定时器事件队列的执行优先级

js是一门“单线程”“非阻塞”语言

event loop:

  1. 执行js代码
  2. 遇到同步代码,按照顺序放入执行栈
  3. 遇到异步代码,不会阻塞后续的代码执行,等到异步请求成功直接将回调函数放入事件队列
  4. 事件队列内部的回调函数并不是马上执行的,而是等到执行栈中的同步代码全部执行完毕,才会从事件队列中取出一个个回调函数放入执行栈,执行栈在继续它的工作。

异步:通常是ajax请求、setTimeout、setInterval、i/o操作、onClick(用户操作)等等

看到这里,应该就可以理解了:为什么onClick的事件不能准时执行?因为可能在它推入到事件队列时,执行栈还没有为空,正在执行其它同步代码

这里就直接引用一张图片来协助理解:
图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题