异步/等待不适用于VueX getter,但适用于日志

Async/Await not working for VueX getter but works for log(异步/等待不适用于VueX getter,但适用于日志)
本文介绍了异步/等待不适用于VueX getter,但适用于日志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个userID的Convos对象,我需要遍历该对象,并且在循环内,我需要调用Firebase以获取相应的用户名,然后返回一个包含Convos、用户名和UserID的对象。

我已经尝试使用异步/等待,从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();
}

推荐答案

为什么会发生这种情况?

因为您同步调用了异步函数。
让我们简化您的代码。

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

    asyncFunction();
}

此时,您的getConvosObj()将不返回任何内容,因为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,而无需调用操作。
我厌倦了重构/编写代码,所以如果您想使用该插件,请在Google上搜索一些示例:)

我对原始代码进行了很多重构,所以应该有一些打字错误或错误。
如果您找到一个,请修改。

这篇关于异步/等待不适用于VueX getter,但适用于日志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)