简体   繁体   中英

Async/Await with Vuex dispatch

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});
    }

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM