问题
话不多说,间接上代码剖析:
<div class="outer">
<div class="inner"></div>
</div>
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
new MutationObserver(function () {console.log('mutate');
}).observe(outer, {attributes: true})
function onClick() {console.log('click');
setTimeout(function () {console.log('timeout')
}, 0);
Promise.resolve().then(function () {console.log('promise')
});
outer.setAttribute('data-random', Math.random());
}
outer.addEventListener('click', onClick);
inner.addEventListener('click', onClick);
// inner.click();
对于以上代码,间接在页面点击触发,会打印出什么样的日志程序?
如果在代码最初应用 js
触发:inner.click()
,又会是怎么的打印程序呢?
解答
点击 outer
的打印后果:click promise mutate timeout
就是失常的 eventloop
程序,着重说 inner
的后果。
点击 inner
的打印后果:click promise mutate click promise mutate timeout timeout
inner.click()
触发 inner
的打印后果:click click promise mutate promise timeout timeout
为什么会产生这样的区别?
触发 inner
会有事件冒泡,同时触发 outer
事件,所以会有两次 onclick
事件执行
不同点在于:
- 页面点击触发,此时执行栈为空,会向宏工作队列增加两个
onclick
,执行第一个时产生promise、mutate
,增加到微工作队列,产生timeout
,增加到宏工作队列,也就是第二个onclick
后边,而后执行栈为空,执行微工作对列,打印promise、mutate
,微工作对列边空,执行宏工作对列,即第二个onclick
,反复以上。 js
触发最要害的不同在于他会在最初多一行代码,也就是执行栈是有script
的,执行inner.click()
,打印inner
的click
,增加promise、mutate
到微工作队列,增加timeout
到宏工作队列,而后检测执行栈是否为空,发现冒泡触发的outer.click()
事件,执行栈依然不为空,打印outer
的click
,增加promise
到微工作队列,增加mutate
时,雷同的一个曾经被增加,所以跳过,后边持续失常执行。