JavaScript任务调度、宏任务和微任务
来自的博客 小提琴(点击嘿): HTML: 当为JavaScript任务调度、宏任务和微任务,javascript,event-handling,Javascript,Event Handling,来自的博客 小提琴(点击嘿): HTML: 当为内部div运行这篇文章时,我得到的结果是 click mutate click mutate promise promise timeout timeout 我很难明白这是怎么回事。 执行应该是 第一个处理程序(宏任务) 处理所有微任务 第二个处理程序(宏任务) 处理所有微任务 设置超时(宏任务) 设置超时(宏任务) 考虑到这一点,我希望日志输出: click promise mutate click promise mutate timeout
内部div运行这篇文章时,我得到的结果是
click
mutate
click
mutate
promise
promise
timeout
timeout
我很难明白这是怎么回事。
执行应该是
第一个处理程序(宏任务)
处理所有微任务
第二个处理程序(宏任务)
处理所有微任务
设置超时(宏任务)
设置超时(宏任务)
考虑到这一点,我希望日志输出:
click
promise
mutate
click
promise
mutate
timeout
timeout
不确定为什么只有在处理了两个click事件处理程序之后才执行承诺。理想情况下,第一个承诺应该在第一次变异后执行,但我们可以看到,情况显然并非如此。有人知道为什么吗?(使用firefox 54.0)当您单击元素时,自然会首先输出click
,因为它上面有一个click事件处理程序,并且在click事件处理程序函数中的first事件中记录单词“click”
接下来是setTimeout(函数(){},0)代码>。这会暂停JavaScript的执行,就像C中的线程/进程产出一样。它要到稍后才会执行,所以我们稍后再讨论这个问题
因为您实际上并没有对承诺做任何事情,所以它会立即解决,第二次退出
突变发生在第三个中,因为DOM是从上到下读取的,并且在承诺解析后直接对data random
属性进行突变
最后,既然DOM已经被读取完毕,那么超时将在第四次读取时结束
由于到调用它的位置,超时从内部
记录两次。这可以从以下事实中看出:console.log(This)
在onclick
中提供与setTimeout相同的上下文(function(){console.log(This)},0)代码>。由于与延迟的设置超时一起,它会尝试先从子
触发,然后从父触发(技术上单击)
因此,您最终会:
click
promise
mutate
timeout
timeout
单击
、承诺
和变异
日志总是一个接一个地出现,乘以您同时单击的元素数。超时
日志始终排在最后
//让我们抓住那些元素
var outer=document.querySelector('.outer');
var inner=document.querySelector('.inner');
//让我们听一听屏幕上的属性更改
//外部元素
新的MutationObserver(函数(){
console.log('mutate');
}).观察(外部、{
属性:true
});
//这里有一个点击侦听器…
函数onClick(){
console.clear();//为了清晰起见添加了
console.log('click');
setTimeout(函数(){
log('timeout');
}, 0);
Promise.resolve().then(函数()){
console.log(“承诺”);
});
outer.setAttribute('data-random',Math.random());
}
//…我们将附加到这两个元素
inner.addEventListener('click',onClick);
outer.addEventListener('click',onClick)代码>
外部
内部的
当您单击元素时,自然会首先输出click
,因为它上面有一个click事件处理程序,并且在click事件处理程序函数中的first事件中有“click”一词的日志
接下来是setTimeout(函数(){},0)代码>。这会暂停JavaScript的执行,就像C中的线程/进程产出一样。它要到稍后才会执行,所以我们稍后再讨论这个问题
因为您实际上并没有对承诺做任何事情,所以它会立即解决,第二次退出
突变发生在第三个中,因为DOM是从上到下读取的,并且在承诺解析后直接对data random
属性进行突变
最后,既然DOM已经被读取完毕,那么超时将在第四次读取时结束
由于到调用它的位置,超时从内部
记录两次。这可以从以下事实中看出:console.log(This)
在onclick
中提供与setTimeout相同的上下文(function(){console.log(This)},0)代码>。由于与延迟的设置超时一起,它会尝试先从子
触发,然后从父触发(技术上单击)
因此,您最终会:
click
promise
mutate
timeout
timeout
单击
、承诺
和变异
日志总是一个接一个地出现,乘以您同时单击的元素数。超时
日志始终排在最后
//让我们抓住那些元素
var outer=document.querySelector('.outer');
var inner=document.querySelector('.inner');
//让我们听一听屏幕上的属性更改
//外部元素
新的MutationObserver(函数(){
console.log('mutate');
}).观察(外部、{
属性:true
});
//这里有一个点击侦听器…
函数onClick(){
console.clear();//为了清晰起见添加了
console.log('click');
setTimeout(函数(){
log('timeout');
}, 0);
Promise.resolve().then(函数()){
console.log(“承诺”);
});
outer.setAttribute('data-random',Math.random());
}
//…我们将附加到这两个元素
inner.addEventListener('click',onClick);
outer.addEventListener('click',onClick)代码>
外部
内部的
我不会以你的例子结束。Firefox仍然会记录点击变异点击mut
click
promise
mutate
timeout
timeout