JS中的async和await

今天遇到了一个问题,大概问题就是存在两个操作:一个基于axios的异步请求,用于获取服务器某个状态;二是使用步骤一种获取的状态拼接链接跳转页面。

问题代码

主要代码如下:

click(){
    this.$store.dispatch('cModule/getWslaDetails', item.bhYyxx)
    this.selectTableKey = item.bhYyxx
}

步骤一

其中dispatch对应的action代码如下:

get(URLS.XXX, {layyId: params}).then(function (data) {
    commit('detailData', data)
    if (data.success === false) {
        Fd.notice.error({
            title: '错误',
            desc: '获取详情数据失败,请联系管理员!',
            duration: 8
        })
    }
})

这是一个异步的请求,使用commit更新$store里面的值。

步骤二

针对selectTableKey有一个监听函数:

watch: {
  selectTableKey (newVal, oldVal) {
    if (newVal) {
      this.$emit('selectNode', newVal)
    }
  }
}

父组件中的selectNode对应的事件是获取detailData中的id,然后和selectTableKey一起拼接一个链接打开新页面。

但是,新页面打开异常!!!

问题分析

拼接链接的时候,detailDataidselectTableKey不匹配,id是上一次selectTableKey对应的id

也就是说,detailData的异步操作还没有结束,链接就拼接好了。

说到最后,就是异步请求同步的问题。

解决方案:asyncawait

由于这个地方使用了vuex,但是vuexaction貌似本身是不支持同步的。这个时候就想到了asyncawait两个关键字。

这个两个关键字主要是与Promise搭配起来用。

总结一下:

  • 必须与Promise一起使用
  • await后面接一个会return new promise的函数并执行它
  • await只能放在async函数里

修改action函数

getWslaDetails({ commit, state }, params) {
  return new Promise((resolve, reject) => {
    get(URLS.xxxx, {layyId: params}).then(function (data) {
        commit('detailData', data)
        if (data.success === false) {
          Artery.notice.error({
            title: '错误',
            desc: '获取数据失败,请联系管理员!',
            duration: 8
          })
      }
      resolve(data);
    }).catch(e => {
      reject(e)
    })
  })
}

action函数返回一个Promise对象。

修改调用方法

async click(){
    const res = await this.$store.dispatch('cjshModule/getWslaDetails', item.bhYyxx)
    if (res) {
        this.selectTableKey = item.bhYyxx
    }
}
  • 在调用该方法的地方使用async声明函数
  • dispatch的地方使用await关键字
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×