https://opendocs.alipay.com/support/01rb6o

红任务微任务:https://zhuanlan.zhihu.com/p/257069622,https://www.jianshu.com/p/7d0a1c1b3853

 

 

js 是单线程执行的,js中的任务按顺序一个一个的执行,但是一个任务耗时太长;

那么后面的任务就需要等待,为了解决这种情况,将任务分为了同步任务和异步任务;

而异步任务又可以分为微任务和宏任务【执行的时候保持先进先出原则】。

从script开始,先执行同步代码,遇到宏任务和微任务先标记暂停执行,把同步代码执行完毕。开始第一轮循环:

第一步,看看有没有微任务,存在微任务的话,那么就执行所有的微任务。第二步,微任务都执行完之后,执行第一个宏任务,先执行标记的第一个宏任务,在执行这个宏任务先执行同步代码,如果遇到宏任务和微任务依然先标记暂停。

这一轮结束,准备执行第二轮标记的红任务【在这之前先执行上一轮留下的微任务】

 

 

 

setTimeout(() => {

    console.log('s1')

    Promise.resolve().then(() => {

        console.log('p1')

        setTimeout(() => {

            console.log('s3')

        })

    })

})

setTimeout(() => {

    console.log('s2')

    Promise.resolve().then(() => console.log('p2'))

})

10467

VM276:2 s1

VM276:4 p1

VM276:11 s2

VM276:12 p2

VM276:6 s3

标记红任务,setTimeout1和setTimeout2,开始循环

VM374:1 Uncaught SyntaxError: Invalid or unexpected token

第一轮循环:执行第一个红任务setTimeout1,先打印s1,遇到Promise-then微任务不执行标记遇到Promise1。此时有微任务Promise1和红任务setTimeout2

VM729:1 Uncaught SyntaxError: Invalid or unexpected token

第二轮循环,有微任务先执行微任务,先执行Promise1,打印p1.然后遇到红任务setTimeout3不执行。队列又有俩个任务队列,宏任务,setTimeout2和setTimeout3

VM1299:1 Uncaught SyntaxError: Invalid or unexpected token

第三轮循环,因为暂时没有微任务只有俩个宏任务,先进先出原则,先执行setTimeout2宏任务,直接打印s2,遇到微任务Promise2,此时有任务队列微任务Promise2和红任务setTimeout3

VM1781:1 Uncaught SyntaxError: Invalid or unexpected token

第四轮循环,先执行微任务Promise2,直接打印p2,此时任务队列只有setTimeout3

VM1921:1 Uncaught SyntaxError: Invalid or unexpected token

第五轮循环,没有微任务只有宏任务,直接执行宏任务标记setTimeout3,最后打印s3,整个任务队列结束

VM2204:1 Uncaught SyntaxError: Invalid or unexpected token

结论,从script外壳宏任务开始,先执行同步代表,标记异步任务(微任务和宏任务)放在任务队列,每次开始新一轮宏任务开始之前,先把当前上一轮遗留下来的微任务的队列清掉才开始执行这一轮宏任务,任务队列保证先进先出原则

VM3232:1 Uncaught SyntaxError: Invalid or unexpected token

 

 

 

 

 二:只有运行完await语句,才把await语句后面的全部代码加入到微任务行列,所以,在遇到await promise时,必须等await promise函数执行完毕才能对await语句后面的全部代码加入到微任务中。

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')
VM1782:1 script start
VM1782:8 async2 end
VM1782:17 Promise
VM1782:27 script end
VM1782:5 async1 end
VM1782:21 promise1
VM1782:24 promise2
undefined
VM1782:13 setTimeout
先直接打印script start,然后执行async1,直接打印async2 end,遇到await为标记微任务放到队列,在继续执行setTimeout放到任务队列宏任务,继续执行,遇到Promise,直接打印同步代码Promise,遇到then1和then2为微任务放任务队列。最后打印打印同步代码script end,至此一轮结束,任务队列有await,setTimeout,then1和then2三个任务队列


VM1871:1 Uncaught SyntaxError: Unexpected identifier
开始第一轮:先清空当前微任务,await和then1,then2,所以拉出await标记打印async1 end 在拉出then1,打印promise1,此时发现还有then2微任务,打印promise2。最后执行宏任务setTimeout,打印setTimeout
VM1876:1 Uncaught SyntaxError: Invalid or unexpected token