21-vue中使用async和await來實現同步和異步


場景如下:現在的邏輯是根據后端API的返回數據修改echart的option中的series.data,然后執行setOption方法,渲染圖標,但是遇到的問題是,后端API可以正常返回數據,但是根據console的顯示是先執行了setOption方法,后執行了API數據賦值給series.data,所以圖表渲染不出想要的數據,代碼如下

  methods: {
    initChart() {
      this.chart = echarts.init(document.getElementById(this.id));
      fetchOverview().then(response => { 
        console.log('1--')
        console.log(response.items)
        console.log('2--')
        this.option.series[0].data = response.items
      }).catch(error => {
        console.log(error);
      })
      console.log('a----')
      console.log(this.option.series[0].data)
      console.log('b-----')
      this.chart.setOption(this.option);
    },
  }

瀏覽器console輸出如下

說明fetchOverview默認是異步執行的,及沒有阻塞fetchOverview這個函數后面的內容先執行(所以先輸出了a---和b---),而如果要是fetchOverview改成同步執行的話需要使用async和await結合使用

1.async/await場景

這是一個用同步的思維來解決異步問題的方案,當前端接口調用需要等到接口返回值以后渲染頁面時。

2.名詞解釋

 async

    async的用法,它作為一個關鍵字放到函數前面,用於表示函數是一個異步函數,因為async就是異步的意思,異步函數也就意味着該函數的執行不會阻塞后面代碼的執行,async函數返回的是一個promise 對象。async 函數也是函數,平時我們怎么使用函數就怎么使用它,直接加括號 且 使用 .then的方法(參考https://www.jianshu.com/p/ab767311589d

 await

   await的含義為等待。意思就是代碼需要等待await后面的函數運行完並且有了返回結果之后,才繼續執行下面的代碼。這正是同步的效果,那么它在等待什么呢,它后面跟着什么呢?其實它后面可以放任何表達式,不過我們更多放的是一個promise對象的表達式(我立即是.then這種方式執行的)。注意await關鍵字,只能放在async函數里面!!!

所以修改后的代碼如下

 methods: {
    async initChart() {
      this.chart = echarts.init(document.getElementById(this.id));
      await fetchOverview().then(response => { 
        console.log('1--')
        console.log(response.items)
        console.log('2--')
        this.option.series[0].data = response.items
      }).catch(error => {
        console.log(error);
      })
      console.log('a----')
      console.log(this.option.series[0].data)
      console.log('b-----')
      this.chart.setOption(this.option);
    },
  }

console輸出如下

符合預期!!!

 

備注:在vue的mount階段執行的函數都是順序執行,不會阻塞的,所以如果希望mount階段的函數也是阻塞的,需要額外寫一個async函數,然后把需要同步執行的函數寫到里面,然后在mount階段調用這個額外寫的函數,例如

    async renderData() {
      await this.getBusinessLinesAndDepartments()
      if (this.workFlowData) {
        // 查看 或 審批流程
        _.forEach(JSON.parse(this.workFlowData.workflowSteps), (step) => {
          if (_.values(step)[0].active) {
            this.currentStep = _.keys(step)[0]
          }
        })
        this.form_temp = JSON.parse(this.workFlowData.meta)
        this.initBusinessLines(false, this.form_temp.department)
      } else {
        // 創建流程
        this.currentStep = 'apply'
      }
      await this.permissionCheck()
    },
  },
 
  mounted() {
    this.renderData()
  },

如果寫成

   mounted() {
     this.renderData()
     this.permissionCheck() 寫成這樣,則permissionCheck會先於renderData(會請求后端獲取數據)執行
   },

  

 報錯:Can not use keyword 'await' outside an async function

參考:https://blog.csdn.net/qq_39040192/article/details/94142398

// 注意response 前面的async
        await searchService(search_key).then(async response => {
          var service_one_id = response.results[0].id
          // _.forEach(response.results, (item) => {
          //   service_ids.push(item.id)
          // })

          await deleteService(service_one_id).then(response => {   # 如果response前面滅有async,這個await會報錯
            // 設置新的審批信息變量
            _.forEach(workflowSteps, (step) => {
              var step_name = _.keys(step)[0]
              var step_info = _.values(step)[0]
              if (step_name == 'op_approve') {
                step_info['approve_result'] = true
              }
              if (['delete_service', 'end'].includes(step_name)) {    // 通過的下一個步驟
                step_info['active'] = true
              } 
              workflowStepsParam.push({[step_name]: step_info})
            })
          }).catch(error => {
            workflowStepsParam = workflowSteps
            console.log(error)
          })
        }).catch(error => {
          workflowStepsParam = workflowSteps
          console.log(error)
        })

 

 

 

 

參考:

https://www.cnblogs.com/jiangds/p/9139743.html

http://blog.sina.com.cn/s/blog_13d06fc1f0102wzfr.html

https://www.jianshu.com/p/ab767311589d

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM