¿Cómo se cancela Ajax? ¿Debería cancelarse?
/ 5 min read
Cancelar Ajax
Si estás familiarizado con xhr
, sabrás que Ajax se puede cancelar desde el lado del cliente utilizando XMLHttpRequest.abort()
. Por supuesto, en la actualidad no es común escribir xhr
a mano, excepto en entrevistas. En la ampliamente conocida biblioteca axios
, hay dos formas de cancelar una solicitud:
Primero, está el antiguo cancelToken
:
Luego, está la nueva (aunque no tan nueva) AbortController
:
Una vez que el cancelToken
o la signal
se pasan a axios
, se invocará XMLHttpRequest.abort()
de alguna manera.
El cancelToken
utiliza el patrón de publicación-suscripción para notificar a axios
sobre la cancelación de la solicitud. Aunque esta parte está implementada por axios
en sí, se basa en una propuesta de tc39 llamada cancelable promises proposal, que fue desechada.
Por otro lado, AbortController
es una interfaz que ya se puede utilizar en los navegadores. Como su nombre lo indica, es un controlador diseñado específicamente para abortar acciones. El ejemplo que se muestra en mdn también utiliza una solicitud Ajax, pero con la moderna y popular función fetch
. Esto demuestra que la implementación de axios
es consistente con la de fetch
.
Otros usos de AbortController
Por supuesto, AbortController no solo se utiliza para cancelar una solicitud Ajax. Al examinar la documentación de la especificación DOM, se pueden encontrar otros dos ejemplos de uso:
Un ejemplo práctico es cancelar la escucha de eventos utilizando AbortController:
Al pasar signal
a AddEventListener
, se puede utilizar abort()
para cancelar la escucha de eventos. Este método es especialmente útil para funciones de devolución de llamada anónimas.
Otro ejemplo es utilizarlo para cancelar una promesa. Este es un método más conciso y autoexplicativo… aunque en realidad, no es necesario utilizar AbortController para lograr esta funcionalidad, solo se necesita encontrar una forma de obtener el reject
de la promesa. Creo que el enfoque principal de este ejemplo es aprender a utilizar onabort
de la señal:
En resumen, la señal es simplemente un emisor simple y su funcionalidad se centra en cancelar una determinada operación. Si en algún caso no se desea implementar un objeto pubsub personalizado, esto es todo lo que se necesita.
La introducción de AbortController llega a su fin, ¿alguien ha olvidado gradualmente el título? Por último, me gustaría discutir si cancelar Ajax realmente sirve de algo.
Cancelar o no cancelar, esa es la cuestión
De hecho, esta cancelación de Ajax es solo una charla interna del frontend, el backend no sabe que se debe interrumpir, la solicitud enviada seguirá ejecutándose, a menos que el backend la maneje de manera especial, incluso si cancelas una solicitud de 10 segundos, el backend seguirá trabajando arduamente.
Entonces, ¿tiene sentido la “optimización” que vemos en algunos artículos, donde se menciona “cancelar solicitudes y mantener solo la última”?
Vamos a analizarlo según el caso. Para las solicitudes de modificación de datos como POST, incluso si la respuesta es lenta, el servidor ya está procesando la solicitud, cancelar el POST anterior y enviar uno nuevo es simplemente un comportamiento tonto.
En el caso de las solicitudes GET, y solo para algunas operaciones extremas, puede haber cierto efecto. Por ejemplo, si se intenta obtener una tabla muy larga y no se recibe respuesta, el usuario puede realizar una búsqueda rápida y obtener una pequeña cantidad de datos para mostrar, y cuando finalmente llegue la tabla larga, los datos de la búsqueda se sobrescribirán. En esta situación, la cancelación es realmente efectiva. También existe la cancelación de descargas y cargas, aunque probablemente se use muy poco.
Por último, mencionaré un beneficio que tiene sentido pero que en realidad no es muy útil: después de cancelar, se ahorra una posición de solicitud. Después de todo, los navegadores tienen un límite en la cantidad de solicitudes simultáneas para un mismo dominio. En la mayoría de los casos, el uso de un timeout es más práctico que cancelar. A menos que haya cinco o seis solicitudes extremadamente lentas en cola, el cambio de turno sigue siendo bastante rápido…
Mi recomendación personal es que esta supuesta “cancelación” es un manejo especial para casos extremadamente particulares. Es suficiente con saber que existe, no es necesario cancelar solicitudes en los interceptores sin motivo.