原文链接:https://segmentfault.com/a/1190000013212944
实际运行发现有两点和文章说的不一样:
- 不管在哪种任务里出现了UI的修改(包括添加节点、修改颜色、修改节点内容等),UI渲染会立即执行(在debugger状态下能看到),不会等到任务队列执行完毕
【更正:UI的修改(包括添加节点、修改颜色、修改节点内容等),会立即更新应用程序的状态。微任务队列清空后,事件循环会检查当前是否需要重新渲染UI,如果需要则渲染UI视图。debugger状态可能在微任务队列中强行插入了一个是否需要重新渲染UI视图的任务,所以在断点处也能看到UI被重新渲染】 - MutationObserver的callback回调函数是异步的,只有在全部DOM操作完成之后才会调用callback(参考)。也就是说,不管是用户点击事件onclick,还是js触发的click,执行的结果是一样的,只会触发一个mutate。
还有一点需要注意,如果没有debugger,那么在alert(‘锚点’)的时候,看到inner的内容其实还是begin而不是end,我想这跟alert的阻断也有关系(参考)
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
var i = 0;
// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
debugger
console.log('mutate');
}).observe(outer, {
attributes: true
});
// Here's a click listener…
function onClick() {
i++;
if(i === 1) {
inner.innerHTML = 'end';
debugger
}
console.log('click');
setTimeout(function() {
alert('锚点');
inner.style.backgroundColor = 'green';
console.log('timeout');
debugger
}, 0);
Promise.resolve().then(function() {
console.log('promise');
inner.appendChild(document.createElement('span'));
debugger
});
outer.setAttribute('data-random', Math.random());
debugger
}
// …which we'll attach to both elements
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
输出:
click
click
promise
mutate
promise
timeout
timeout
另外还有这个:
document.body.style.backgroundColor = 'green'
while(true) {}
body颜色会变绿色吗
document.body.style.backgroundColor = 'red'
setTimeout(() => {
while(true) {}
})
body颜色会变红色吗
document.body.style.backgroundColor = 'yellow'
Promise.resolve().then(() => {
while(true) {}
})
body颜色会变黄吗
直接在浏览器运行,只有第二条会变颜色,其它2条会直接卡死,可是如果在死循环前加上debugger,那么会发现其实以上三种情况下,body的颜色都已经被改变了。
inner.style.backgroundColor = 'green';
while(true){
debugger
}
setTimeout(() => {
debugger
while(true) {}
})
Promise.resolve().then(() => {
debugger
while(true) {}
})
在微任务队列清空后,事件循环会检查当前是否需要重新渲染UI,如果需要则渲染UI视图。
宏任务
宏任务包含创建文档对象、解析HTML、执行主线JavaScript代码、更改当前URL以及各种事件,例如页面加载、输入、网络事件和定时器等等。宏任务运行完成后,浏览器继续其他的任务调度,如重新渲染页面或者垃圾回收。
微任务
微任务包括promise、回调函数、DOM发生变化等。微任务更新应用程序的状态,必须在浏览器任务继续执行其他任务(渲染UI视图或者进行下一个宏任务)之前执行。
本文探讨了JavaScript中的事件循环机制,澄清了UI渲染的实际过程。在宏任务和微任务执行期间,UI更新会立即反映,微任务队列清空后,事件循环检查并可能触发UI重新渲染。MutationObserver的callback是异步的,且alert可能导致阻塞。理解这些机制对于优化JavaScript性能至关重要。

5921

被折叠的 条评论
为什么被折叠?



