web-dev-qa-db-fra.com

Actions asynchrones / en attente dans Vuex

Je me demande comment utiliser les actions async/wait dans Vuex. Les docs fournissent cette syntaxe à titre d'exemple:

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // wait for `actionA` to finish
    commit('gotOtherData', await getOtherData())
  }
}

En suivant cet exemple, j'ai:

import Vue from 'vue';
import Vuex from 'vuex';
import * as firebase from 'firebase';

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        // other state vars here
        resource: null
    },
    mutations: {
        // saveValues
        setResource(state, payload) {
            state.resource = payload;
        }
    },
    actions: {
        async getResource({ commit, dispatch }) {
            var resource
            console.log('resource1: ' + resource)
            Vue.http.get('https://mysite/api/getResource')
                .then((response) => {
                    console.log('get resource')
                    var data = response.body;
                    resource = data.access_resource;
                    console.log('resource2: '+ resource)
                    commit('setResource', resource);
                    var foo = store.getters.resource;
                    console.log('resource3: ' + foo);
                }, (error) => {
                    console.log(error);
                });
        },
        async getSomeApi({ commit, dispatch }) {
            console.log('getting api');
            await dispatch('getResource');
            var resource = store.getters.resource;
            console.log('resource4: ' + resource);
            Vue.http.get('https://somesite/api/someapi?resource=' + resource)
                .then((response) => {
                    console.log("got something from somesite")
                    var data = response.body;
                    // do something with data -> payload
                    dispatch('saveValues', payload);
                }, (error) => {
                    console.log(error);
                });
        }
    },
    getters: {
        resource(state) {
            return state.resource;
        }
    }
});

Cependant, même en suivant l'exemple de syntaxe trouvé dans les documents, lorsque j'exécute ce code, l'async/wait semble être complètement ignoré. Lorsque je regarde les journaux, je vois, dans l'ordre suivant:

  • getting api
  • resource1: undefined
  • resource4: null
  • get resource
  • resource2: <expected-value>
  • resource3: <expected-value>

Je m'attends à ce que les instructions console.log s'impriment dans l'ordre numérique. J'apprécierais que quelqu'un clarifie ce que je fais mal.

11
pillravi

Vous n'êtes pas awaiting la promesse Vue.http.get() dans la méthode getResource(), donc await dispatch('getResource') résoudra avant la résolution de la requête HTTP.

Dégrossi:

async getResource() {
    let response

    try {
        response = await Vue.http.get('https://mysite/api/getResource')
    } catch (ex) {
        // Handle error
        return
    }

    // Handle success
    const data = response.body
}
15
Decade Moon