async / await

113 阅读3分钟

async / await

  • async/await 是 ECMAScript 2017(ES8)引入的一种用于处理异步操作的语法糖。它是基于 Promise 的异步编程模型的一种更简洁、更直观的写法
  • async 是一个用于声明异步函数的关键字,用于修饰函数定义。异步函数内部可以使用 await 关键字来暂停函数的执行,等待一个 Promise 对象的解析结果,并将解析的结果返回。

示例1:

  1. 如果在async函数内部没有 await,此时async是没有意义的,函数内部就全是同步内容
        async function p(){
               let j = 1
                console.log(j) 
              }
              p()
             console.log(2) 
  • 打印结果为1 、 2同步执行的
  • 注意:此时p()为一个promise对象,async用于修饰一个函数,表示该函数是异步的,返回一个promsie对象
  1. 如果在async函数内部遇到了awaitawait下面那一行的代码会以异步处理,相当于.then的回调
 async function p(){
       let j = await 1
        console.log(j)
      }
      p()
     console.log(2)
  • 打印结果为2 、 1
  • awaitconsole.log(j) 变为了 异步执行

示例2:

async function foo(){
        let num = await 100  
        console.log(num)
    }
  • 相当于下面代码
function foo(){
        return Promise.resolve(100).then(num => {
            console.log(num)
        })
    }
  • await下面的都相当于是放到了.then()的回调函数中

示例3:

  • async函数内部return语句返回的值,会成为then方法回调函数的参数。
async function fn(){
            // 内部按理说,应该写一些异步的代码
            return 'hello async'
        }
        fn().then(res => {
            console.log(res)  // hello async
        })

async基本语法:

  1. 函数声明
async function fn(){}
  1. 函数表达式
let fnn = async function(){}
  1. 对象方法
let bj = {
            name : 'kk',
            async sayhi() {
                   console.log(111);
            }
        }
  1. 箭头函数
let p = async () => {}
  • 可理解为 async 一般都是写在 function 前面
  • 注意: async 必须和await搭配使用 否则只是把函数变成peomise对象

await

  1. await不能单独存在,await必须在async函数内使用,写在普通函数内会报错。
  2. await后面一般会跟着一个promise对象, 返回该对象的结果(成功或失败)

示例1:

const sleep = s => new Promise(resolve => setTimeout(() => resolve(s), s * 1000))
async function fn() {
            let res = await sleep(3)
            // 下面的代码,相当于.then(res => {})
            console.log(res)  // 3
        }
        fn()
  • 过三秒打印3
  • 相当于直接把await 后面promise的结果给了res

示例2:

const sleep = (s) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(s);
        }, s * 1000);
    });
};

async function func1() {
    // 使用 await 暂停函数执行,等待 sleep(1) 的结果
    const res1 = await sleep(1);
    console.log('res1:', res1);
    
    // 继续执行,再次使用 await 暂停函数执行,等待 sleep(3) 的结果
    const res2 = await sleep(3);
    console.log('res2:', res2);
}

async function func2() {
    // 使用 await 暂停函数执行,等待 sleep(2) 的结果
    const res3 = await sleep(2);
    console.log('res3:', res3);
    
    // 继续执行,再次使用 await 暂停函数执行,等待 sleep(4) 的结果
    const res4 = await sleep(4);
    console.log('res4:', res4);
}

// 调用异步函数 func1() 和 func2()
func1();
func2();

  • await 阻塞的是async function里面的代码,不会阻塞外面的函数的执行
  • 注意: await sleep(4); 解析这句代码 sleep(4)执行是同步的,不等待。

字节跳动的面试题

  • 输出的顺序

   async function async1() {
            // 这里的代码是同步的 
            console.log('async1 start')    // 2 
            await async2() // 这里要执行,同步,不等待
            // 相当于放到了.then() 异步   微任务
            console.log('async1 end')      // 6
            console.log(666)    // 7
        }
        async function async2() {
            console.log('async2')       // 3
        }

        console.log('script start')      // 1

        setTimeout(function () { // 宏任务
            console.log('setTimeout')  // 9
        }, 0)

        async1();

        new Promise(function (resolve) {
            console.log('promise1')    // 4
            resolve();
        }).then(function () { // 微任务
            console.log('promise2') // 8
        });
        console.log('script end')   // 5
  • 输出顺序
  • image.png