异步编程解决方案|青训营笔记

27 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第10天。异步编程一直是写js时常见的问题。本文介绍了三种异步编程解决方案,包括Promise、async和generator

Promise

Promise的三种状态

  1. 待定 pending
  2. 成功 fulfilled
  3. 失败 rejected

Promise中只有两种状态改变模式:

  1. pending --> fulfilled;
  2. pending --> rejected

Promise的方法

  1. promise.then(): 返回一个Promise对象,状态根据内部执行结果决定
  2. promise.catch:用于捕获异常的方法,差不多是.then()方法写错误回调函数的语法糖。
  3. promise.finally:最后不管promise的状态如何,都会执行的代码。
  4. promise.all: Promise.all([promise1,promise2,promise3,promise4]).then()。所有promise都变为fulfilled才触发then()的resolve。如果有一个状态变成了rejected,那么all方法的状态就会变成rejected。
  5. promise.race
  6. promise.resolve:返回一个状态为fulfilled的Promise对象,值为参数中回调函数return的值。
  7. promise.reject:返回一个状态为rejected的Promise对象,值为参数中回调函数return的值。

练习题

function fn() {
    return new Promise((resolve) => {
        console.log("Promise1")
        fn1()
        setTimeout(() => {
            console.log('Promise2')
            resolve()
            console.log('Promise3')
        }, 0)
    })
    }
async function fn1() {
    var p = Promise.resolve().then(() => {
        console.log('Promise6')
    })
    await p.then(() => {
        console.log('Promise7')
    })
    console.log('end')
}
console.log('script');
setTimeout(() => {
    console.log('setTimeout')
}, 0)
fn().then(() => {
    console.log('Promise4')
})
// script promise1 Promise6 Promise7 end setTimeout promise2 promise3 promise4
  

async

是promise和generator函数的语法糖。promise函数虽然解决了回调地狱的问题,但是语意不够清晰,generator函数需要手动调用next(),使得代码向下运行,不够便利。

async函数调用时会直接执行到内部第一个await后面的语句,之后的语句需要阻塞到await后面的语句执行完成。

特性

  1. async函数内部会返回一个promise对象
  2. await能获取到promise状态改变后的,若后面不是promise对象,则将它隐式转为已经正常处理的promise对象的resolve值。
  3. 若await后promise的状态是reject,则await后的代码不会执行,async返回状态为reject的promise
  4. 若async函数内部有await,则await下面的代码被阻塞,await后的promise对象状态为fulfilled时才往下执行。
async function fn(){
    setTimeout(()=>{
        console.log(1)
    },0)
    Promise.resolve().then(()=>{console.log(4)});
    await setTimeout(function(){
        console.log(5)
    },0);
    //等价于
    // await Promise.resolve(setTimeout(function(){
    //     console.log(5);
    // }),0).then(()=>undefined);
    await Promise.resolve().then(()=>{
        console.log(6)
    })
    Promise.resolve().then(()=>{
        console.log(7)
    })
    console.log(3);
}
fn();
// 4 6 3 7 1 5

generator

Generator 生成器函数,返回 遍历器对象。返回到遍历器对象中,使用对象的.next()方法控制函数内部的代码向下执行,执行到下一个 yield 关键字之前的代码,或者函数结尾处。并且next()方法会返回一个对象,对象内部有value,done两个属性{value:yield后的值/undefined,done:true/false};done为false时,表示已经走到了函数末尾。