JS是单线程的(避免多个线程同时操作DOM造成的困扰),非阻塞的(eventloop)
既然JS是单线程的,那就意味着JS中执行的任务需要排队, 也就产生了 任务队列
而任务又分为两种: 同步任务、异步任务
所有同步任务都在主线程上执行, 形成一个执行栈(stack)
异步任务将会被放到 任务队列(先进先出) 中

MacroTasks - 宏任务
我们常见的以下任务都属于宏任务
script(整体代码)- 定时器(
setTimeout,setInterval) I/OUI交互事件浏览器渲染
MicroTasks - 微任务
每个宏任务执行完成之后都会立即执行微任务队列中的所有任务
Promise.then/catch/finally()MutationObserverqueueMicrotask(fn)
测试:
const button = document.querySelector('.btn')
button.addEventListener('click', () => {
Promise.resolve().then(() => console.log('Microtask1'))
console.log('Listener1')
})
button.addEventListener('click', () => {
Promise.resolve().then(() => console.log('Microtask2'))
console.log('Listener2')
})
// 然后点击button
上面代码的输出结果为:
Listener1
Microtask1
Listener2
Microtask2
然后, 我们使用JS来模拟用户点击事件
// same code...
button.click() // 因为此时该语句位于 stack 中并未执行结束, 所以不会执行微任务
输出结果为:
Listener1
Listener2
Microtask1
Microtask2