三分钟搞懂async和await

2,178 阅读2分钟

三分钟搞懂async和await

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

大家好!

上次写了一个Promise的极简教程,通过promise.then()方法可以像同步方法那样来写异步方法。

Generator函数是ES6提供的一种异步编程解决方案,也叫构造器函数,它可以让函数的执行暂停,函数的执行流挂起,为改变执行流程提供了可能,形式上也是一个普通函数。

ES2017 引入了async函数,它是Generator函数的语法糖,async和await要实现的是Generator函数的特性,即暂停函数执行,让异步函数变为同步执行,采用async+await+解构函数的方式,会让写法更加类似一条同步方法,使得异步操作更为方便。

1 同步执行

我们看下面这个简单同步执行的例子:

示例 三个依次执行的函数

 function funOne() {
     return ("执行第一个函数");
 }
 ​
 function funTwo() {
     return ("执行第二个函数");
 }
 ​
 function funThree() {
     return ("执行第三个函数");
 }
 ​
 function run() {
     console.log(funOne());
     console.log(funTwo());
     console.log(funThree());
 }
 run()

在上述代码中,执行run() 函数,会按代码顺序依次调用funOne() 、funTwo()、funThree(),在打印台打印出:

  • 执行第一个函数
  • 执行第二个函数
  • 执行第三个函数

2 同步执行中加入异步方法

那么,需求来了,现在我们用jquery模拟在funTwo()中,执行一个ajax异步请求,然后我们看run()内的执行顺序。

 function funOne() {
     return ("执行第一个函数");
 }
 ​
 function funTwo() {
     $.ajax({
         url:'./data.json',
         success: (res) => {
             return("执行第二个回调函数");
         }
     })
 }
 ​
 function funThree() {
     return ("执行第三个函数");
 }
 ​
 function run() {
     console.log(funOne());
     console.log(funTwo());
     console.log(funThree());
 }
 run()

我们会发现,funTwo()是异步编程,要等同步函数执行完后,再调用它,所以它的执行顺序到了最后:

  • 执行第一个函数
  • 执行第三个函数
  • 执行第二个回调函数

3 asycn调整执行顺序

但在开发中,我们是期望函数按照 funOne()->funTwo()-funThree()的顺序执行,这是我们就可以用到promise对象和async和await的组合,来实现同步执行。

首先,用promise对象的方式,来改造一下funTwo():

 function funTwo() {
     return new Promise=((resolve,reject) => {
         $.ajax({
             url:'./data.json',
             success: (res) => {
                 resolve("执行第二个回调函数");
             }
         })
     })
 }

然后,我们把async放到run( )函数前,把await放到funTwo()前面上,告诉程序,要等待funTwo()执行结束后,再执行funThree ()

 async function run() {
     console.log(funOne());
     console.log(await funTwo());
     console.log(funThree());
 }
 run()

那么,在打印台中,打印出来的顺序,就和同步执行的顺序一样,并且第三个函数可以拿到第二回调函数传过来的数据了。

  • 执行第一个函数
  • 执行第二个回调函数
  • 执行第三个函数