首页 > 解决方案 > 我的 Vue.js Vuex 商店有 2 个发出 GET 请求的操作。第二个动作需要第一个动作的响应才能工作。怎么做?

问题描述

我有 2 个动作可以发出 GET 请求并将响应保存在 Vuex 商店中。第一个操作getVersion()获取游戏的最新版本,并且需要该版本才能发出第二个 GET 请求。现在我已经在第二个动作中对版本进行了硬编码,但是,我的目标是将它连接到 URL 中。

可悲的是,我不确定如何从函数内部访问它。Console.log(state.version) 出于某种原因返回 null,即使它不应该是。我从 App.vue 内部调用这些函数,如下所示:

mounted(){
    this.$store.dispatch('getVersion')
    this.$store.dispatch('getChampions')
}

Vuex商店

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        version: null,
        champions: null
    },
    mutations: {
        version(state, data){
            state.version = data.version
        },
        champions(state, data){
            state.champions = data.champions
        }
    },
    actions: {
        getVersion({commit}){
            axios.get("http://ddragon.leagueoflegends.com/api/versions.json")
            .then((response) => {
                commit('version', {
                    version: response.data[0]
                })
            })
            .catch(function (error) {
                console.log(error);
            })
        },
        getChampions({commit, state}){
            axios.get("https://ddragon.leagueoflegends.com/cdn/9.24.1/data/en_US/champion.json")
            .then((response) => {
                commit('champions', {
                    champions: response.data.data
                })
            })
            .catch(function (error) {
                console.log(error);
            })
        }
    },
    getters: {
        version: (state) => {
            return state.version;
        },
        findChampion: (state) => (id) => {
            let championId = id.toString();
            let champion = Object.values(state.champions).find(value => value.key === championId);

            return champion
        }
    }
})

标签: javascriptvue.jsvuex

解决方案


有了这部分:

this.$store.dispatch('getVersion')
this.$store.dispatch('getChampions')

第二次调度不会等待第一次调度完成。这意味着它在第一个有机会完成获取版本之前触发。

您需要创建一个应在dispatch调用第二个之前解决的承诺。

你可以尝试这样做:

async mounted(){
    await this.$store.dispatch('getVersion')
    await this.$store.dispatch('getChampions')
}

或者如果你不想使用async/await

this.$store.dispatch('getVersion').then(() => { 
    this.$store.dispatch('getChampions');
});

在操作中您应该添加return到请求中(这很重要):

return axios.get(...

推荐阅读