消息队列
settimeout是异步方法,会排到消息队列去执行,也就是执行异步方法的队列称为消息队列。
js多线程
js主要是多线程执行的,而执行非异步方法的部分称为主线程,消息队列其实也是一个线程,称为副线程,而主线程执行完毕才会执行副线程。
宏任务与微任务
副线程(消息队列)并非只有一个,为了执行效率和顺序分为宏任务线程与微任务线程,只有微任务进程执行完才会执行宏任务进程
**宏任务(Macrotasks):**js同步执行的代码块,setTimeout、setInterval、XMLHttprequest、setImmediate、I/O、UI rendering等。
**微任务(Microtasks):**promise、process.nextTick(node环境)、Object.observe, MutationObserver等。
浏览器执行的顺序:
事件轮询
正常的js执行逻辑
(1)执行主代码块,这个主代码块也是宏任务
(2)若遇到Promise,把then之后的内容放进微任务队列
(3)遇到setTimeout,把他放到宏任务里面
(4)一次宏任务执行完成,检查微任务队列有无任务
(5)有的话执行所有微任务
(6)执行完毕后,开始下一次宏任务。
其中23456就是事件轮询
Generator 函数
Generator函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权
该函数返回一个状态机,必须要靠状态机.next()才能执行
执行过程只需要记住一句话
执行到yield就暂停,返回yield后面值,第一次执行参数无用,再次执行参数赋给yield前面的表达式。
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函数的语法糖,原理是通过Generator函数加自动执行器来实现的,这就使得async、await跟普通函数一样了,不用再一直next执行了
async function doSomething1(){
let x = await 'hhh'
return x
}
console.log(doSomething1())
doSomething1().then(res => {
console.log(res)
})
打印结果:
Promise {<pending>}
hhh
总结
所以本质上async await是generator与promise结合的语法糖
三者调用请求的对比案例:
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的语法
})
}
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
})
}