今天遇到了一个问题,大概问题就是存在两个操作:一个基于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
一起拼接一个链接打开新页面。
但是,新页面打开异常!!!
问题分析
拼接链接的时候,detailData
的id
和selectTableKey
不匹配,id是上一次selectTableKey
对应的id
。
也就是说,detailData
的异步操作还没有结束,链接就拼接好了。
说到最后,就是异步请求同步的问题。
解决方案:async
和await
由于这个地方使用了vuex
,但是vuex
的action
貌似本身是不支持同步的。这个时候就想到了async
和await
两个关键字。
这个两个关键字主要是与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
关键字