#javascript #vue.js #async-await #axios
#javascript #vue.js #асинхронный -ожидание #axios
Вопрос:
Я пытаюсь создать простое приложение, в котором у меня есть список поставщиков, и я хочу добавить / удалить их … одна и та же проблема для обоих случаев
когда я пытаюсь удалить элемент или и когда я пытаюсь добавить элемент (поставщик)
Вот ситуация:
Provider.vue: * загрузка поставщиков из и API (просто так)
<template lang="html">
<div class="container">
<h1 class="h2">{{ $t('default.titles.providers') }}</h1>
<button class="btn btn-success my-3 float-right" @click="addProvider">{{ $t('default.buttons.add') }}</button>
<template v-if="showError">
<div class="clearfix"></div>
<tw-loading-error :message="this.error"></tw-loading-error>
</template>
<template v-else>
<table class="table table-hover table-sm">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">{{ $t('default.provider.name') }}</th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr v-for="(provider, index) in providerList" :key="index">
<th scope="row">{{index 1}}</th>
<td>{{provider.provider_name}}</td>
<td :title="$t('default.buttons.edit')">
<router-link :to="{ name: 'edit-provider', params: { provider } }">
<Edit2Icon
class="pointer">
</Edit2Icon>
</router-link>
</td>
<td :title="$t('default.buttons.delete')">
<router-link class="delete" :to="{ name: 'delete-provider', params: { provider } }">
<DeleteIcon
class="pointer">
</DeleteIcon>
</router-link>
</td>
<td :title="$t('default.buttons.add-client')">
<router-link class="edit" :to="{ name: 'add-provider-user',
params: {
provider_id: provider.id_provider,
provider_name: provider.provider_name
}}">
<UserPlusIcon class="pointer"></UserPlusIcon>
</router-link>
</td>
</tr>
</tbody>
</table>
</template>
</div>
</template>
<script>
import ProviderService from './../../../services/provider.service'
import { Edit2Icon, DeleteIcon, UserPlusIcon } from 'vue-feather-icons'
import LoadingError from './../../shared/alerts/LoadingError.vue'
export default {
name: "Provider",
data() {
return {
providerList: [],
error: '501: cannot load the providers :(',
showError: false
}
},
components: {
'tw-loading-error': LoadingError,
Edit2Icon, DeleteIcon, UserPlusIcon
},
methods: {
getProviders() {
ProviderService.getProviders().then(
response => {
this.providerList = response.data
},
error => {
this.showError = true
this.error = error
}
)
},
addProvider() {
this.$router.push({name: "add-provider"})
},
},
mounted() {
this.getProviders();
}
}
</script>
<style lang="css" scoped>
.pointer {
cursor: pointer;
}
.delete {
color: red;
}
</style>
provider.service.js : * очень просто .. Я либо получаю весь поставщик, либо удаляю поставщика
import axios from '../axios/axios-conf'
import authHeader from './auth-header';
class ProviderService {
async getProviders() {
const response = await axios.get('/providers', { headers: authHeader() })
return response
}
async deleteProvider(id){
try {
return await axios.delete('/provider/delete/' id)
} catch (error) {
return error
}
}
}
export default new ProviderService()
DeleteProvider.vue: * вот виновник
<template lang="html">
<div class="container">
<h1 class="h2">{{$t('default.titles.delete')}} {{provider.name}}?</h1>
<div class="container">
<button class="btn btn-danger" @click="deleteProvider(provider.id)">{{$t('default.buttons.yes')}}</button>
<button class="btn btn-sm btn-secondary" @click="goBack">{{$t('default.buttons.no')}}</button>
</div>
</div>
</template>
<script>
// import axios from './../../../axios/axios-conf'
import ProviderService from './../../../services/provider.service'
export default {
name: "DeleteProvider",
data() {
return {
provider: {
id: null,
name: null
}
}
},
components: {
},
methods: {
async deleteProvider(id){
let c = confirm("Do you really want to delete it? You will not be able to restore this data again!")
if(c){
this.delete(id)
.then(success => {
return success
})
.catch(error => {
return error
})
this.goBack()
}
},
async delete(id){
let response = await ProviderService.deleteProvider(id)
return response
},
checkParams(){
if(JSON.stringify(this.$route.params) === '{}'){
this.goBack()
}
},
goBack(){
this.$router.push({ name: 'provider'})
}
},
mounted() {
this.provider.name = this.$route.params.provider.provider_name
this.provider.id = this.$route.params.provider.id_provider
},
created() {
this.checkParams()
}
}
</script>
<style lang="css" scoped>
.pointer{
cursor: pointer
}
</style>
API-интерфейсы работают безупречно .. они делают то, что ожидается.. проблема возникает, когда я пытаюсь удалить провайдера, VueJS перенаправляет меня (маршрутизатор) так быстро в список провайдеров, что элемент не исчезает (тот, который удален). Только после того, как я обновлю страницу (либо через F5, либо перейду на другую страницу и обратно, чтобы отобразить ее снова), она проецируется.
Итак, дело в том, что он успешно удален, но страница не ждет или удаление не проецирует его сразу.
Что я делаю не так? У меня есть async / await в моем коде для всех функций (отчаянная ситуация требует отчаянных мер: D)
PS: стоит упомянуть: это происходит только время от времени .. иногда это работает нормально (поэтому элемент не отображается .. иногда мне приходится обновлять страницу)
Спасибо
Ответ №1:
this.goBack()
Неправильно ожидает завершения асинхронной функции. this.delete(id)
Строка ниже и this.goBack()
строки выполняются параллельно, поскольку delete
это асинхронный вызов.
Кроме того, вы также можете использовать try...catch
блок вместо цепочки обещаний. Посмотрите на мои изменения ниже:
async deleteProvider(id){
let c = confirm("Do you really want to delete it? You will not be able to restore this data again!")
if(c){
try{
const success = await this.delete(id)
return success;
} catch(error){
return error;
} finally {
this.goBack(); // If you want to go back only on success, move this line inside the try block before the `return`.
}
}
}