Saltar al contenido principal

Cancelar un fetch

AbortController ofrece una nueva forma de cancelar los fetches que ya no se consideran relevantes. Esto se puede conectar a fetch mediante el segundo parámetro RequestInit.

Resource​

La integración es sencilla con RestEndpoint mediante el miembro signal:

const abort = new AbortController();
const AbortableArticle = CoolerArticleResource.get.extend({
signal: abort.signal,
});
// ...somewhere later trigger cancellation
abort.abort();

Endpoint​

Además, se puede agregar fácilmente una funcionalidad similar a cualquier endpoint usando miembros personalizados.

type Params = { id: string };

const UserDetail = new Endpoint(
function ({ id }: Params) {
const init: RequestInit = {};
if (this.signal) {
init.signal = this.signal;
}
return fetch(this.url({ id }), init).then(res => res.json()) as Promise<
typeof payload
>;
},
{
url({ id }: Params) { return `/users/${id}` },
signal: undefined as AbortSignal | undefined,
},
);
const abort = new AbortController();
const AbortableUserDetail = UserDetail.extend({
signal: abort.signal,
});
// ...somewhere later trigger cancellation
abort.abort();

Cancelar cuando cambian los parámetros​

A veces el usuario tiene la oportunidad de completar un campo que afecta los resultados de una llamada de red. Si es un campo de texto, podría escribir muy rápido y generar muchas solicitudes de red.

Usar useCancelling() cancelará automáticamente las solicitudes en curso si los parámetros cambian antes de que se resuelva la solicitud.

import { useSuspense, useCancelling } from '@data-client/react';
import { TodoResource } from './resources/Todo';

export default function TodoDetail({ id }: { id: number }) {
  const todo = useSuspense(useCancelling(TodoResource.get, { id }), {
    id,
  });
  return <div>{todo.title}</div>;
}
Resultado
Store▶

Prueba a hacer clic en » muy rápido. Si incrementas antes de que se resuelva la petición, esta se cancelará y no deberías ver resultados en el store.

Advertencia

Ten cuidado al usar esto con muchos componentes independientes que obtienen los mismos argumentos (par Endpoint/params) con useSuspense(). Esta solución aborta los fetches por componente, lo que significa que podrías terminar cancelando un fetch que otro componente todavía necesita.