首先说明
- 首先在JavaScript中,有同步代码和异步代码.这点很清晰.
- 代码的执行优先级顺序是,同步代码执行优先级最高,只用等同步代码执行完毕之后,才会执行异步代码.这点也很清晰.
- 上面说的宏任务和微任务都全部都是异步代码.
- 所以,在谈论宏任务和微任务时,就是在谈论异步代码.
所谓的宏任务和微任务
- 宏任务:比如定时器(
setTimeout,setTimeInterval
), DOM元素的事件(比如按钮点击
). 这些都属于宏任务. - 微任务: Promise相关的任务就叫微任务.
可以这么简单理解,除了Promise相关,其他的丢在Event-Loop里的都叫宏任务.
执行原则.
请看下面这段代码:
function app() {
setTimeout(() => {
console.log('A')
Promise.resolve().then(() => {
console.log('B')
})
})
console.log('C')
Promise.resolve().then(() => {
console.log('D')
Promise.resolve().then(() => {
console.log('F')
setTimeout(() => {
console.log('E')
})
})
})
}
上述代码的输出顺序会是什么呢?
先给出几个原则:
-
执行第一原则:所以的js代码顺序逻辑是:先执行完同步代码,等同步代码执行完毕之后,才会去执行EventLoop里的异步代码.
-
执行第二原则: 同一层级下,微任务执行的优先级永远大于宏任务.
-
在同层级下,当微任务中,包含微任务时,除非等当前微任务全部调用完毕,否则,同级下的宏任务将无法执行.
代码分析:
-
当程序执行到:
console.log('C')
时,即表明全局的同步代码已经执行完毕,开始执行异步代码(也就是宏微任务.) 输出C
-
现在上下的运行代码都在
EventLoop
中,根据上述原则同级下,微任务永远大于宏任务执行
. 所以先执行Promise.resolve().then(() => { console.log('D')
. 输出D
. -
由于代码下面还有一个微任务,根据上述第三点原则,继续执行微任务
Promise.resolve().then(()=>{console.log('F')})
输出F
. -
此时,同级微任务执行完毕, 在执行
setTimeout(()=>{ console.log('A')
在输出A
. -
同级下,微任务永远大于宏任务执行
仍然是这个原则,所以先执行Promise.resolve().then(()=>{console.log('B')
输出B
最后输出E
.
最后的输出结果是: [C] [D] [F] [A] [B] [E]
网友评论