前言
之前对js的执行顺序一直搞得很迷茫,最近考虑换跳槽,又仔细回顾了下这块,又给捡起来了
JavaScript 代码执行顺序
1. js的执行顺序,先同步后异步
2. 异步中任务队列的执行顺序: 先微任务microtask队列,再宏任务macrotask队列
(微任务优先级高于宏任务的前提是:同步代码已经执行完成。)
3. Promise 里边的代码属于同步代码,.then() 中执行的代码才属于异步代码
微任务包括 process.nextTick
,promise
,MutationObserver
。
宏任务包括 script
, setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
。
仔细看一遍下面的代码就清楚了
console.log('script start') // 同步
async function async1() {
await async2()
console.log('async1 end') // 异步
}
async function async2() {
console.log('async2 end') // 同步
}
async1()
setTimeout(function() {
console.log('setTimeout') // 宏任务
}, 0)
new Promise(resolve => {
console.log('Promise') // 同步
resolve()
})
.then(function() {
console.log('promise1') // 异步
})
.then(function() {
console.log('promise2') // 异步
})
console.log('script end') // 同步
//
script start
async2 end
Promise
script end
async1 end
promise1
promise2
setTimeout
分析
首先执行 同步代码:
- 首先执行 console.log(‘script start’)
- 执行 async1() 的时候,马上执行了 async2函数:console.log(‘async2 end’),在此期间它会阻塞,延迟执行await语句后面的语句。
- 顺序执行 new Promise()中的同步函数:console.log(‘Promise’)
- 最后执行 console.log(‘script end’)。
上面是同步执行的代码,然后看剩下的异步执行的代码:
首先,setTimeout是 宏观任务,排除到最后,剩下微观任务:
async function async1() {
await async2()
console.log('async1 end')
}
new Promise(resolve => {
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
-
然后根据先入先出的对列方式,先执行 await async2() 后面阻碍的函数 console.log(‘async1 end’)
-
执行promise的resolve函数,也就是接下来的两个then: console.log(‘promise1’) ---- console.log(‘promise2’) ;
new Promise(resolve => {
resolve()
})
- 最后执行的是 setTimeout函数 console.log(‘setTimeout’) ;
综上所述,以上代码执行的顺序是:
1.script start
2.async2 end
3.Promise
4.script end
5.async1 end
6.promise1
7.promise2
8.setTimeout