问题
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