Digamos que cuando se carga un componente hago una solicitud asíncrona. Ese componente también tiene un botón de envío que el usuario puede presionar, lo que activa una función que se basa en el resultado de esa solicitud original. ¿Cómo retraso la ejecución de la función activada hasta que finaliza la solicitud asíncrona?
Si eso no tiene sentido déjame dar un ejemplo. MyComponent
realiza una solicitud asíncrona getRandomColor()
en el mounted
. La plantilla de MyComponent
tiene <button @click="handleClick">
. handleClick
llama a alguna función saveColor()
. ¿Cómo me aseguro de que no se llame a saveColor()
hasta que termine mi async getRandomColor()
?
Actualmente estoy usando Vue.js pero creo que esta pregunta se aplica a todo javascript.
Puede lograr esto agregando :disabled
en su elemento de botón. El valor de :disabled
se basará en la respuesta. es decir, si la respuesta estará allí, habilítela, de lo contrario, desactívela.
Demostración de trabajo:
const app = Vue.createApp({ el: '#app', data() { return { buttonText: 'Call Me!', apiResponse: [], isDisabled: false } }, methods: { saveColor() { console.log('saveColor method call'); } }, mounted() { axios.get("https://jsonplaceholder.typicode.com/users").then(response => { this.apiResponse = response.data; // Here we are getting proper response. hence, button is getting enabled. }).catch((error) => { console.warn('API error'); }); } }) app.mount('#app')
<script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <div id="app"> <button v-on:click="saveColor()" :disabled="!apiResponse.length">{{ buttonText }}</button> </div>
Agregar el fragmento a continuación según el comentario agregado por el autor de la publicación.
¿Qué pasa si no quiero usar el botón deshabilitado? ¿Hay alguna manera de hacer que el controlador de botones espere a que finalice la solicitud antes de continuar con la ejecución?
const app = Vue.createApp({ el: '#app', data() { return { buttonText: 'Call Me!', apiResponse: [], isDisabled: false } }, methods: { saveColor() { console.log('saveColor method call'); } }, mounted() { axios.get("https://jsonplaceholder.typicode.com/users").then(response => { this.apiResponse = response.data; // Here we are getting proper response. hence, button is getting enabled. }).catch((error) => { console.warn('API error'); }); } }) app.mount('#app')
<script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <div id="app"> <button v-on:click.prevent="apiResponse.length ? saveColor() : {}">{{ buttonText }}</button> </div>