Async/Await with Vuex dispatch

删除回忆录丶 提交于 2020-07-05 07:08:46

问题


I am making a loader for some components in my app.

Here is my component:

        mounted() {
            this.loading = true;

            this.getProduct();
        },
        methods: {
            async getProduct() {
                await this.$store.dispatch('product/getProducts', 'bestseller');

                console.log(123);

                this.loading = false;
            }
        },

Vuex action:

getProducts({commit}, type) {
        axios.get(`/api/products/${type}`)
            .then(res => {
                let products = res.data;
                commit('SET_PRODUCTS', {products, type})
            }).catch(err => {
            console.log(err);
        })
    },

The problem is in this line: await this.$store.dispatch('product/getProducts', 'bestseller');

I expect the code will stop at that line and wait for data is loaded from AJAX call and then set the loading is false;

But it isn't. The loading is still set false and the console.log run before my data is ready.

I already tried to move async/await into Vuex action and it worked. However, I didn't get the difference between them.

Below code is worked for me:

Component:

mounted() {
            this.loading = true;

            this.$store.dispatch('product/getProducts', 'bestseller').then((res) => {
                this.loading = false;
            });
        },

Vuex action:

async getProducts({commit}, type) {
        let res = await axios.get(`/api/products/${type}`);

        commit('SET_PRODUCTS', {products: res.data, type});
    }

回答1:


Change this:

getProducts({commit}, type) {
    axios.get(`/api/products/${type}`)
        .then(res => {
            let products = res.data;
            commit('SET_PRODUCTS', {products, type})
        }).catch(err => {
        console.log(err);
    })
},

To this:

getProducts({commit}, type) {
    return axios.get(`/api/products/${type}`)
        .then(res => {
            let products = res.data;
            commit('SET_PRODUCTS', {products, type})
        }).catch(err => {
        console.log(err);
    })
},

Should work.

axios.get returns a promise. You would need to return that promise in order to let await wait for it. Otherwise, you are implicitly returning undefined and await undefined would immediately resolve.




回答2:


You can not await a function without promise

await this.$store.dispatch('product/getProducts', 'bestseller');

This function return data or call new action

getProducts({commit}, type) {
    axios.get(`/api/products/${type}`)
        .then(res => {
            let products = res.data;
            commit('SET_PRODUCTS', {products, type})
        }).catch(err => {
        console.log(err);
    })
},

And this function return promise because of async function

async function return promise

async getProducts({commit}, type) {
    let res = await axios.get(`/api/products/${type}`);

    commit('SET_PRODUCTS', {products: res.data, type});

}

Now using above function now you can use

await this.$store.dispatch('product/getProducts', 'bestseller');

with await key word Or you can return axios because axios also return a promise.



来源:https://stackoverflow.com/questions/55700815/async-await-with-vuex-dispatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!