Асинхронный / ожидающий с отправкой Vuex

#javascript #vue.js #async-await #vuex

#javascript #vue.js #асинхронный-ожидающий #vuex

Вопрос:

Я создаю загрузчик для некоторых компонентов в своем приложении.

Вот мой компонент:

         mounted() {
            this.loading = true;

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

                console.log(123);

                this.loading = false;
            }
        },
 

Действие Vuex:

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

Проблема в этой строке: await this.$store.dispatch('product/getProducts', 'bestseller');

Я ожидаю, что код остановится на этой строке и будет ждать загрузки данных из вызова AJAX, а затем установит загрузку false ;

Но это не так. Загрузка все еще установлена false и console.log выполняется до того, как мои данные будут готовы.

Я уже пытался переместить async / await в действие Vuex, и это сработало. Однако я не понял разницы между ними.

Приведенный ниже код работает для меня:

Компонент:

 mounted() {
            this.loading = true;

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

Действие Vuex:

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

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

Ответ №1:

Измените это:

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

К этому:

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

Должно сработать.

axios.get возвращает обещание. Вам нужно будет вернуть это обещание, чтобы разрешить await его ожидание. В противном случае вы неявно возвращаетесь undefined и await undefined немедленно разрешаете.

Комментарии:

1. «вы неявно возвращаете undefined, и ожидание undefined немедленно разрешится» Это помогло в моем случае. Спасибо!

2. совершенно забыл вернуть обещание axios, спасатель жизни!

3. woooo я рад найти это решение, большое вам спасибо!

Ответ №2:

Вы не можете ожидать функцию без обещания

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

Эта функция возвращает данные или вызывает новое действие

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

И эта функция возвращает обещание из-за асинхронной функции

 async function return promise

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

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

}
 

Теперь, используя вышеуказанную функцию, теперь вы можете использовать

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

с ключевым словом await
Или вы можете вернуть axios, потому что axios также возвращает обещание.