消息隊(duì)列
settimeout是異步方法,會(huì)排到消息隊(duì)列去執(zhí)行,也就是執(zhí)行異步方法的隊(duì)列稱為消息隊(duì)列。
js多線程
js主要是多線程執(zhí)行的,而執(zhí)行非異步方法的部分稱為主線程,消息隊(duì)列其實(shí)也是一個(gè)線程,稱為副線程,而主線程執(zhí)行完畢才會(huì)執(zhí)行副線程。
宏任務(wù)與微任務(wù)
副線程(消息隊(duì)列)并非只有一個(gè),為了執(zhí)行效率和順序分為宏任務(wù)線程與微任務(wù)線程,只有微任務(wù)進(jìn)程執(zhí)行完才會(huì)執(zhí)行宏任務(wù)進(jìn)程
**宏任務(wù)(Macrotasks):**js同步執(zhí)行的代碼塊,setTimeout、setInterval、XMLHttprequest、setImmediate、I/O、UI rendering等。
**微任務(wù)(Microtasks):**promise、process.nextTick(node環(huán)境)、Object.observe, MutationObserver等。
瀏覽器執(zhí)行的順序:
事件輪詢
正常的js執(zhí)行邏輯
(1)執(zhí)行主代碼塊,這個(gè)主代碼塊也是宏任務(wù)
(2)若遇到Promise,把then之后的內(nèi)容放進(jìn)微任務(wù)隊(duì)列
(3)遇到setTimeout,把他放到宏任務(wù)里面
(4)一次宏任務(wù)執(zhí)行完成,檢查微任務(wù)隊(duì)列有無(wú)任務(wù)
(5)有的話執(zhí)行所有微任務(wù)
(6)執(zhí)行完畢后,開始下一次宏任務(wù)。
其中23456就是事件輪詢
Generator 函數(shù)
Generator函數(shù)是協(xié)程在 ES6 的實(shí)現(xiàn),最大特點(diǎn)就是可以交出函數(shù)的執(zhí)行權(quán)
該函數(shù)返回一個(gè)狀態(tài)機(jī),必須要靠狀態(tài)機(jī).next()才能執(zhí)行
執(zhí)行過(guò)程只需要記住一句話
執(zhí)行到y(tǒng)ield就暫停,返回yield后面值,第一次執(zhí)行參數(shù)無(wú)用,再次執(zhí)行參數(shù)賦給yield前面的表達(dá)式。
function *doSomething() {
let x = yield 'hhh'
console.log(x)
let y = yield (x + 3)
console.log(y)
let z = yield (y * 3)
return (x * 2)
}
let newDoSomething = doSomething()
console.log(newDoSomething.next(1))
console.log(newDoSomething.next(2))
console.log(newDoSomething.next())
console.log(newDoSomething.next())
{value: "hhh", done: false}
2
{value: 5, done: false}
undefined
{value: NaN, done: false}
{value: 4, done: true}
async、await
async、await是Generator函數(shù)的語(yǔ)法糖,原理是通過(guò)Generator函數(shù)加自動(dòng)執(zhí)行器來(lái)實(shí)現(xiàn)的,這就使得async、await跟普通函數(shù)一樣了,不用再一直next執(zhí)行了
async function doSomething1(){
let x = await 'hhh'
return x
}
console.log(doSomething1())
doSomething1().then(res => {
console.log(res)
})
打印結(jié)果:
Promise {<pending>}
hhh
總結(jié)
所以本質(zhì)上async await是generator與promise結(jié)合的語(yǔ)法糖
三者調(diào)用請(qǐng)求的對(duì)比案例:
promise
function getList() {
return new Promise((resolve, reject) =>{
$axios('/pt/getList').then(res => {
resolve(res)
}, err => {
reject(err)
})
})
}
function initTable() {
getList().then(res => {
console.log(res)
}).catch(err => {
this.$message(err) // element的語(yǔ)法
})
}
generator
function *initTable(args) {
const getList = yield getlist(args)
return getList
}
function getList() {
const g = initTable(this.searchParams)
const gg = g.next().value
gg.then(res =>{
this.total = res.data.count
if (res.data.list) {
this.tableList = res.data.list
this.tableList.forEach(e => {
e.receiveAmt = format(e.receiveAmt)
})
} else {
this.tableList = []
}
})
}
async
async initTable() { // table列表查
const getData = await getList(this.searchParams)
return getData
},
getList() {
this.initTable().then(res =>{
this.tableList = res.data.list
})
}