從Jake Archibald的博客JavaScript的任務調度,宏任務和Microtasks
小提琴(點擊嘿嘿):https://jsfiddle.net/1rpzycLf/
HTML:
<div class="outer">
<div class="inner"></div>
</div>
JS:
// Let's get hold of those elements
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
console.log('mutate');
}).observe(outer, {
attributes: true
});
// Here's a click listener…
function onClick() {
console.log('click');
setTimeout(function() {
console.log('timeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise');
});
outer.setAttribute('data-random', Math.random());
}
// …which we'll attach to both elements
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
當運行這個作品爲inner div
我得到的結果是ar e
click
mutate
click
mutate
promise
promise
timeout
timeout
我正在努力研究這是怎麼回事。 執行應該是
- 首先處理程序(宏任務)
- 過程所有 Microtasks
- 第二處理程序(宏任務)
- 過程所有 Microtasks
- 的setTimeout(宏任務)
- SetTimeout(Macrotask)
考慮到這一點,我的日誌期待輸出,而不是:
click
promise
mutate
click
promise
mutate
timeout
timeout
不知道爲什麼promises
正在執行兩個點擊的事件處理程序的已被處理之後。第一個承諾應該在第一個mutate
之後理想地執行,但我們可以看到顯然不是這種情況。有人知道爲什麼(使用Firefox 54.0)
我沒有結束你的例子。 Firefox仍然記錄'點擊' '變異' '點擊' 'mutate'首先。點擊'inner'時發生這種情況 - 編輯奇怪,當我運行你的代碼片段時,它輸出了不同的東西。 '點擊' 'mutate' 'promise' 'promise' 'timeout' 'timeout' – Aaron
有趣 - 我在其他瀏覽器上也得到了不同的結果。我會更新我的答案來說明這一點。 –
是的,這可能是一個問題。你怎麼知道哪一個是正確的?我也編輯了我的例子,我期待'click''promise''mutate'的執行順序 - 無論如何 – Aaron