Cómo Abortar Solicitudes API y Manejar Errores en Vue.js con VueUse
Introducción
Cuando se trabaja con operaciones asíncronas en aplicaciones Vue, es crucial gestionar las solicitudes de manera eficiente, especialmente cuando se trata de solicitudes potencialmente largas o innecesarias. En este artículo, exploraremos cómo abortar solicitudes utilizando VueUse y manejar los errores lanzados por estas solicitudes abortadas.
Problema
En las aplicaciones web modernas, es común realizar múltiples llamadas API para obtener datos. Sin embargo, hay escenarios en los que podríamos querer cancelar solicitudes en curso, como cuando un usuario navega fuera de una página o cuando una nueva solicitud reemplaza a una existente. Además, necesitamos manejar los errores que pueden ocurrir al abortar estas solicitudes para garantizar una experiencia de usuario fluida.
Contexto
VueUse proporciona un potente composable useFetch
que nos permite realizar solicitudes HTTP con funcionalidad de aborto incorporada. Veamos cómo podemos aprovechar esta característica:
const { abort, canAbort } = useFetch(url);
setTimeout(() => {
if (canAbort.value) abort();
}, 100);
En este ejemplo, podemos abortar una solicitud utilizando la función abort
proporcionada por useFetch
. La propiedad canAbort
indica si la solicitud puede ser abortada.
También podemos establecer un tiempo de espera automático para abortar solicitudes:
const { data } = useFetch(url, { timeout: 100 });
Esto abortará automáticamente la solicitud después de 100 milisegundos.
Solución
Ahora, implementemos una solución que demuestre cómo abortar solicitudes y manejar errores en un componente Vue. Crearemos un componente que obtiene mensajes y permite al usuario cancelar la solicitud haciendo clic en un botón varias veces.
<template>
<div>
<button @click="getMessages">Obtener Mensajes</button>
<div v-if="loading">Cargando...</div>
<ul v-else>
<li v-for="message in messages" :key="message.id">
{{ message.text }}
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useFetch } from '@vueuse/core';
import { defineStore } from 'pinia';
interface Message {
id: number;
text: string;
}
const useStore = defineStore('main', {
state: () => ({
cancellableRequests: new Map<string, { abort: () => void }>(),
}),
});
const store = useStore();
const messages = ref<Message[]>([]);
const loading = ref(false);
const getMessages = async (): Message[] => {
try {
loading.value = true;
const url = '/api/messages';
const token = 'getMessages';
if (store.cancellableRequests.has(token)) {
store.cancellableRequests.get(token)?.abort();
store.cancellableRequests.delete(token);
}
const { execute, abort, data, error } = useFetch(url, {
immediate: false,
})
.get()
.json<{ messages: Message[] }>();
store.cancellableRequests.set(token, { abort });
await execute();
if (error.value) {
if error.value instanceof Error && error.value.name === 'AbortError') {
store.cancellableRquests.delete(token);
return []
}
throw new Error('Algo salió mal. Inténtelo de nuevo más tarde.')
}
return data.value.messages;
} finally {
loading.value = false;
}
};
</script>
En este ejemplo, hemos creado un componente Vue que demuestra cómo abortar solicitudes y manejar errores:
- Definimos un store Pinia para gestionar las solicitudes cancelables.
- La función
getMessages
es responsable de obtener mensajes y manejar el ciclo de vida de la solicitud. - Antes de realizar una nueva solicitud, verificamos si existe una solicitud existente con el mismo token y la abortamos si existe.
- Utilizamos
useFetch
de VueUse para realizar la llamada API. - Almacenamos la función
abort
en nuestro store Pinia, lo que nos permite cancelar la solicitud más tarde si es necesario. - Manejamos errores, incluyendo el
AbortError
, que se lanza cuando se cancela una solicitud. - Devolvemos los mensajes obtenidos si tiene éxito, o un array vacío si la solicitud fue abortada.
- Finalmente, limpiamos eliminando la solicitud de nuestro store y estableciendo el estado de carga en falso.
Esta implementación permite una gestión eficiente de las llamadas API, evitando solicitudes de red innecesarias y mejorando la experiencia general del usuario.
Conclusión
Al implementar esta solución, hemos abordado con éxito la pregunta inicial de cómo abortar solicitudes utilizando VueUse y manejar los errores lanzados por ellas. Este enfoque permite una gestión eficiente de las llamadas API, evitando solicitudes de red innecesarias y mejorando la experiencia general del usuario.