前端异步的一些基本概念

消息队列

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 {}
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
  })
}

你可能感兴趣的:(前端异步的一些基本概念)