Vue中异步:Async和await的使用(echarts画图,DOM渲染的时候,还没有请求到数据)

Vue中异步:Async和await的使用(echarts画图,DOM渲染的时候,还没有请求到数据)

首先看示例:

async function test() {
    console.log(0)
    await console.log(111);//在第一个await表达式出现之前,异步函数内部的代码都是按照同步方式执行的
    console.log(555)	//倒数第二个输出
    console.log(556665)//最后一个输出
 }
 function test1(){
     console.log(22)
 }
test1();
test();
console.log(10);

输出结果:

Vue中异步:Async和await的使用(echarts画图,DOM渲染的时候,还没有请求到数据)_第1张图片

总结:异步方法里面await会阻塞该方法内部后续的进程(等待时间比同步方法久,先执行同步方法)

再看以下示例帮助理解:

let x = 0;
 
async function test() {
    x += await 2;
    console.log(x);	// 输出什么?
}
 
test();
x = 1;

输出3?还是2?正确答案是:2

  1. 首先我们先记住一句话,那就是异步函数(async方式声明的函数)不代表其函数内部的所有代码都是异步方式执行的,这句话什么意思呢?通俗讲就是:在第一个await表达式出现之前,异步函数内部的代码都是按照同步方式执行的,记住这句话以后我们再继续往下看
  2. 那么在test函数内部,哪些代码是按同步方式执行的呢?首先我们可以将x += await 2这行代码稍微变换一下形式,变换为:x = x + await 2,表达式右边的x是取值操作,并且按同步方式执行的,所以在执行到await时,右边的x已经取值完成,并且被取到的值0替换,然后才轮到test函数外的x = 1这行代码执行,x += await 2相当于x = 0 + await 2,所以最终输出:2

现在,我们稍微对上面的代码做一下修改:

let x = 0;
async function test() {
    x = (await 2) + x;// 把await放在x前面
    console.log(x);	 // 这里又输出什么?
} 
test();
x = 1;

输出:3。原因是:await 2这次被放在了x表达式的前面,所以x的取值操作是异步执行的,也就是说x = 1会先被执行,然后才是test函数中x的取值操作,由于test函数中的x形成了闭包,所以x = (await 2) + x相当于x = (await 2) + 1,所以最终输出:3

结论:

上面代码的关键是:test函数中x的取值操作与x = 1这行代码执行顺序先后的问题,所以我们可以得出一个结论:await会阻塞其所在表达式中后续表达式的执行

echarts实现先从后端获取数据再渲染:

再看以下代码注意:async方法中调用别的方法,那么里面的所有方法都是异步:如下示例
 async getData () {
      await this.$http.get('/api/system/cscpCurrentUserDetails').then(response => {
      	this.orgid = response.data.orgIds
      }).catch()//异步方法(这个方法执行完才会执行下面的方法)
      this.getLeakNum()
      this.getLeakList()
      await this.getBarChartData()//这里只是方法名异步,里面的方法没有异步,这样写不能实现想要的效果(要想在方法里面也使用异步,示例如下2)
      this.drawMyChart01()
 }

2、要想在方法里面也使用异步,示例如下:

①:实现先获取数据再渲染:

 async getData () {
      await this.$http.get('/api/system/cscpCurrentUserDetails').then(response => {
      	this.orgid = response.data.orgIds
      }).catch()
      await this.getBarChartData() //调用
       this.drawMyChart01()
    }, 
async getBarChartData() {
      let self = this;
      const BaseUrl = this.$util.getAjaxUrl('type_8')
      const url = BaseUrl + '/api/screen/queryLeakCountForYear'
      var argumentObj = {
        orgId : this.orgid,
      }
     await this.$http.get(url, {params: argumentObj}).then(function(response) {
        if (response.data.status === -1) {
          self.$Message.error({
            content: response.data.msg
          })
        } else {
          for (var i = 0; i < response.data.data.length; i++){
            self.barChartData.xAxisData.push(response.data.data[i].dateTime)
            self.barChartData.data.push(response.data.data[i].num)
          }
         /* self.drawMyChart01()*/

        }
      }).catch(function(error) {
        console.log(error);
      });
       /*self.drawMyChart01()*/
    },

这样就先执行await this.getBarChartData(),等待它获取到数据再执行下面的方法(该方法内部的await不能省略,省略还是不能先获取数据)

接着看第二种Echarts中先获取数据再渲染的方法(上面是一种先获取数据再渲染的方法)

在watch中调用初始化方法,或者在watch中调用画图的方法

②:实现先获取数据再渲染:

watch:{
    barChartData:{//监听该数据(获取到数据后肯定跟初始的默认数据不一样,所以会自动触发)
      handler(){
        this.drawMyChart01()
      },
      deep:true //true 深度监听//深度监听,可监听到对象、数组的变化
    }
  },

直接使用watch或者在组件中使用watch都可以先获取到数据再渲染(因为再数据改变之后又调用了一次渲染的方法)

第三种先获取数据再渲染的方法:

直接在方法内部调用渲染的方法

③:实现先获取数据再渲染:

 async getData () {
      await this.$http.get('/api/system/cscpCurrentUserDetails').then(response => {
      	this.orgid = response.data.orgIds
      }).catch()
       this.getBarChartData()//调用
    }, 
getBarChartData() {//获取后台数据的方法
      let self = this;
      const BaseUrl = this.$util.getAjaxUrl('type_8')
      const url = BaseUrl + '/api/screen/queryLeakCountForYear'
      var argumentObj = {
        orgId : this.orgid,
      }
      this.$http.get(url, {params: argumentObj}).then(function(response) {
        if (response.data.status === -1) {
          self.$Message.error({
            content: response.data.msg
          })
        } else {
          for (var i = 0; i < response.data.data.length; i++){
            self.barChartData.xAxisData.push(response.data.data[i].dateTime)
            self.barChartData.data.push(response.data.data[i].num)
          }
          self.drawMyChart01()//必须写在这里

        }
      }).catch(function(error) {
        console.log(error);
      });
       /*self.drawMyChart01()*/
    },

④:实现先获取数据再渲染:

 async getData () {
      await this.$http.get('/api/system/cscpCurrentUserDetails').then(response => {
      	this.orgid = response.data.orgIds
      }).catch()
       this.getBarChartData()//调用
    },
async getBarChartData() {
      let self = this;
      const BaseUrl = this.$util.getAjaxUrl('type_8')
      const url = BaseUrl + '/api/screen/queryLeakCountForYear'
      var argumentObj = {
        orgId : this.orgid,
      }
     await this.$http.get(url, {params: argumentObj}).then(function(response) {
        if (response.data.status === -1) {
          self.$Message.error({
            content: response.data.msg
          })
        } else {
          for (var i = 0; i < response.data.data.length; i++){
            self.barChartData.xAxisData.push(response.data.data[i].dateTime)
            self.barChartData.data.push(response.data.data[i].num)
          }
         /* self.drawMyChart01()*/

        }
      }).catch(function(error) {
        console.log(error);
      });
       self.drawMyChart01()//写在这里
    },

总结:以上四种写法都可以实现先从后端获取到数据再渲染

你可能感兴趣的:(大前端,Vue.js,vue.js,echarts,javascript)