异步基础

异步的实现原理

例如AJAX,不会立即执行,而是等待请求成功之后才能执行
传递过去不执行,等待结果后再执行的函数,称之为回调函数
实现异步的核心原理:将callback作为参数传递给异步执行函数,当有结果返回之后再触发callback
常见的异步操作:
网络请求
IO操作
定时函数:setTimeout只在指定时间后执行一次
setInterval以指定时间为周期循环执行

异步操作不进入主线程,而是进入“任务队列”

异步执行机制:·分为执行栈和任务队列两步
●主线程空,就会去读取“任务队列”
●异步必须指定回调函数,主线程执行异步任务,就是执行对应的回调函数

异步和event-loop(轮询机制):主线程丛“任务队列”中读取事件

avatar

Node.js的event-loop:不同于浏览器环境

process.nextTick:它指定的任务总是发生在所有异步任务之前
setImmediate:在当前“任务队列”的底部添加事件,它指定的任务总是在下一次
event loop执行(setImmediate指定的回调函数,总是排在setTimeout前面,实际上,这种情况只发生递归调用的时候)

事件绑定算不算异步?

看起来一样
同:同样使用event-loop,
异:事件绑定有明显的订阅-发布模式
异步操作完成后,系统会自动调用;事件绑定之后,需要用户手动调用

异步调用方式

  1. 回调函数callback
    fn2(fn3):fn2和fn3完全耦合在一起,保证fn3是在fn2之后执行的
  2. 事件订阅/发布(ES5)
    如何顺序执行?(保证const asyncFunArr = new AsyncFunArr(fn1, fn2, fn3)中fn函数是顺序执行的)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    class AsyncFunArr {
    constructor (...arr) {
    this.funcArr = [...arr]
    }
    next() {
    const fn = this.funcArr.shift()
    if (typeof fn === 'function') fn()
    }
    run () {
    this.next()
    }
    }
    const asyncFunArr = new AsyncFunArr(fn1,fn2,fn3)

    function fn1 (){
    console.log("Funtion1")
    asyncFunArr.next()
    }

    function fn2 (){
    setTimeout(() => {
    console.log('Function2')
    asyncFunArr.next()
    },500)
    }

    function fn3 () {
    console.log('Function 3')
    asyncFunArr.next()
    }
  3. Promise:函数返回Promise

    1
    2
    3
    4
    5
    6
    7
    8
    function fn2 () {
    return new Promise((resolve,reject) => {
    setTimeout(() => {
    console.log('Function 2')
    resolve()
    },500)
    })
    }
  4. generator:异步函数会通过yield执行,异步函数内通过next激活generator函数的下一步操作(维护内部yield的执行)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function fn2 () {
    setTimeout(() => {
    console.log('Function 2')
    af.next()
    },500)
    }

    function* asyncFunArr (...fn) {
    fn[0]()
    yield fn[1]()
    fn[2]()
    }
    const af = asyncFunArr(fn1,fn2,fn3)

    af.next()
  5. 使用async/await——————Promise-async/await

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function fn2 () {
    return new Promise((resolve,reject)=> {
    setTimeout(() => {
    console.log('Function 2')
    resolve()
    },500)
    })
    }
    async function asyncFunArr(){
    fn1()
    await fn2()
    fn3()
    }
    asyncFunArr()