Async/Await不适用于VueX getter,但适用于日志



我有一个与userIDs卷积的对象,我需要循环通过它,在循环中,我需要调用Firebase来获得相应的userName,然后返回一个具有卷积、userNames和userIDs的对象。

我尝试过使用async/await,从console.log得到的结果是正确的,但在那之后我的返回语句是未定义的。为什么会发生这种情况?他们正在接收相同的对象。

store.jsgetter代码段

getConvosObj: state => {
var convoObj = {};
var userConvos = state.userProfile.convos;
async function asyncFunction() {
for (const key in userConvos) {
if (userConvos.hasOwnProperty(key)) {
const userID = userConvos[key];
var userName;
await fire.database().ref('/users/' + userID + '/userName').once('value', async (snapshot) => {
userName = await snapshot.val();
convoObj[key] = {userName, userID}
})
}
}
console.log(convoObj);   //result: correct object
return convoObj;         //result: undefined
}
asyncFunction();
}

为什么会发生这种情况

因为您同步调用了async函数
让您的代码变得更简单。

getConvosObj: state => {
async function asyncFunction() {
// ...
}
asyncFunction();
}

此时,您的getConvosObj()将返回nothing,因为getConvosObj()asyncFunction()结束之前结束
您需要等到asyncFunction()结束,然后您的代码应该是这样的:

getConvosObj: async state => { // <- changed here
async function asyncFunction() {
// ...
}
await asyncFunction(); // <- changed here too
}

但是您不应该这样做,因为getter在设计上并不意味着异步
这可能有效,但你应该尝试不同的方法。

那么你该怎么办呢

在使用getter之前使用操作

这是一个基本的方法。

异步函数应该在操作中
所以你的商店应该是这样的:

export default () => 
new Vuex.Store({
state: {
convoObj: null
},
mutations: {
updateConvoObj(state, payload) {
state.convoObj = payload;
}
},
actions: {
async fetchAndUpdateConvoObj({ state, commit }) {
const fetchUserData = async userId => {
const snapShot = await fire.database().ref('/users/' + userID + '/userName').once('value');
const userName = snapShot.val();
return {
userName: userName,
userID: userId
}
}
const userConvos = state.userProfile.convos;
let convoObj = {};
for (const key in userConvos) {
if (userConvos.hasOwnProperty(key)) {
const userId = userConvos[key];
const result = await fetchUserData(userId);
convoObj[key] = {
userName: result.userName,
userId: result.userId
}
}
}
commit('updateConvoObj', convoObj);
}
}
});

然后在sample.vue:中使用getter之前调用您的操作

await this.$store.dispatch('fetchAndUpdateConvoObj');
convoObj = this.$store.getters('getConvoObj');

等待数据库并更新存储,然后获取其状态<没有道理吗?>

使用vuexfire将您的商店直接连接到实时数据库

另一种方法是这样。

使用vuexfire,则存储的状态始终是实时数据库的最新状态,因此您可以在不调用操作的情况下调用getter
我已经厌倦了重构/编写代码,所以如果你想使用这个插件,请在谷歌上搜索一些示例:(

我对原始代码进行了大量重构,所以应该有一些拼写错误或错误
plz修订是如果你找到一个。

相关内容

  • 没有找到相关文章

最新更新