zoukankan      html  css  js  c++  java
  • async/await让异步操作同步执行的方法详解

    这篇文章主要给大家介绍了关于async/await让异步操作同步执行的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用async/await具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

     

    一.前言

    我们经常会遇到这样的麻烦事,多个函数按顺序执行,返回结果却不是我们预期的顺序,原因一般是由于异步操作引起的,所以呢,我们需要一种解决方案来处理这种问题,从而使得异步操作按照同步的方式来执行,这样我们就可以控制异步操作输出结果的顺序了

    二.异步操作会带来什么问题

    异步操作可能会许多的问题,下面是常见的两种

    1.函数执行的结果并不是按照顺序返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function fn1(){
     console.log(111)
     setTimeout(function(){
      console.log('wait me 3000')
     },3000)
    }
    function fn2(){
     console.log(222)
    }
    fn1();
    fn2();

    //结果
    //111
    //222
    //wait me 3000

    上面的代码,如果你期待的结果是

    //111
    //wait me 3000
    //222

    那就错了,因为fn1函数里面还有一个函数setTimeout,这两个函数是异步执行的,而fn1和fn2是同步执行的,先执行fn1再执行fn2,在执行fn1的时候打印结果111,三秒后再执行setTimeout,但是在这三秒之前已经执行完了fn2

    那是不是由于setTimeout函数设置的等待时间太久了才会导致的呢?那下面我把时间设为0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function fn1(){
     console.log(111)
     setTimeout(function(){
      console.log('wait me 3000')
     },0)
    }
    function fn2(){
     console.log(222)
    }
    fn1();
    fn2();
    //结果
    //111
    //222
    //wait me 3000

    从结果上看并没有改变,这是应为setTimeout这个函数在执行之前会查看执行队列看看有没有人在排队,如果有,那么将等其他的函数执行完再执行自己,所以不管就算你设置时间为0,也不会改变它最后一个执行

    2.在外部获取不到异步函数里的值

    下面我们看一个最简单的例子,我的需求是要在fn1函数外面打印msg

    1
    2
    3
    4
    5
    6
    function fn1(){
     setTimeout(function(){
      msg='wait me 3000';
     },3000);
    }
    fn1();

    那么怎么样才能获取到msg呢

    使用回调函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function fn1(callback){
     setTimeout(function(){
      msg='wait me 3000';
      callback(msg);
     },3000);
    }
    fn1(data=>{
     console.log(data);//wait me 3000
    });

    使用Promise

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function fn1(){
     return new Promise(function(res,rej){
      setTimeout(function(){
       msg='wait me 3000';
       res(msg);
      },3000);
     })
    }
    fn1().then(data=>{
     console.log(data)
    })

    三.async/await解决方案

    async/await的作用就是使异步操作以同步的方式去执行

    异步操作同步化?

    可以使用Promise中的then()来实现,那么async/await与它之间有什么区别呢

    1.async函数返回的是一个Promise对象

    如果一个函数加了async关键词,这个函数又有返回值,在调用这个函数时,如果函数执行成功,内部会调用Promise.solve()方法返回一个Promise对象,如果函数执行出现异常,就会调用Promise.reject()方法返回一个promise 对象

    要想获取到async函数的执行结果,就要调用Promise的then或catch来给它注册回调函数

    1
    2
    3
    4
    async function fn(){
     return '111'
    }
    console.log(fn());//Promise { '111' }

    既然是Promise对象,因此可以使用then()获取返回的结果

    1
    2
    3
    4
    5
    6
    async function fn(){
     return '111'
    }
    fn().then(data=>{
     console.log(data)//111
    })

    2.await

    上面介绍了async的作用,一般情况下,async与await配合使用才能使异步操作同步化,await就是等待的意思,等待某一个函数执行完之后,后面的代码才能开始执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function fn1(){
     return new Promise(resolve=>{
      setTimeout(function(){
       msg='wait me 3000';
       resolve(msg)
      },3000);
     });
    }
    async function asyncCall(){
     var result=await fn1();
     console.log(result);
    }
    asyncCall();

    如果我们没有等待fn1执行完之后再打印result,那么有可能得到是undefined

    四.总结

    在很多的时候,我们是希望按照同步的方式来获得异步函数的结果,比如登录时,我们必须要在后台返回匹配成功的信息之后才能进行页面跳转,因此,使异步操作同步化这是很重要的知识点,但是这种方案是基于Promise的基础之上的,因此在学习该知识时,一定要对Promise有充分的理解

    好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

  • 相关阅读:
    实体类中的date类型问题
    java.sql.SQLException: validateConnection false
    本地计算机的mysql服务启动后停止
    VUE遇到Windows 64-bit with Unsupported runtime (64) For more information on which environments are supported please see
    有关详细信息, 请使用 -Xlint:unchecked 重新编译。
    mysql出错ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
    WIN7系统如何在文件列表中显示文件夹后缀
    shell 两类执行方法
    Git 报错 error setting certificate verify locations
    maven打包不同jdk版本的包
  • 原文地址:https://www.cnblogs.com/wl-blog/p/15136449.html
Copyright © 2011-2022 走看看