As promessas do JavaScript sempre foram uma grande vitória para a linguagem: elas levaram a uma revolução na codificação assíncrona que melhorou muito o desempenho na Web. Uma deficiência das promessas nativas é que não há uma maneira real de cancelar uma solicitação de busca. fetch…até agora. Uma nova AbortController foi adicionado à especificação JavaScript que permitirá que os desenvolvedores usem um sinal para abortar uma ou várias chamadas de busca.
Aqui está o fluxo de como o cancelamento de uma fetch funciona:
- Criar um
AbortControllerinstância - Essa instância tem um
signalpropriedade - Passe o
signalcomo uma opção de busca para osignal - Chame o
AbortController‘sabortpara cancelar todas as buscas que usam esse sinal.
Abortando um Fetch
A seguir, o senhor verá os detalhes básicos do cancelamento de uma solicitação de busca:
const controller = new AbortController();
const { signal } = controller;
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 1 is complete!`);
}).catch(e => {
console.warn(`Fetch 1 error: ${e.message}`);
});
// Abort request
controller.abort();
Um AbortError ocorre no momento em que o abort para que o senhor possa ouvir as buscas abortadas no catch comparando o nome do erro:
}).catch(e => {
if(e.name === "AbortError") {
// We know it's been canceled!
}
});
Passar o mesmo sinal para vários fetch cancelará todas as solicitações com esse sinal:
const controller = new AbortController();
const { signal } = controller;
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 1 is complete!`);
}).catch(e => {
console.warn(`Fetch 1 error: ${e.message}`);
});
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 2 is complete!`);
}).catch(e => {
console.warn(`Fetch 2 error: ${e.message}`);
});
// Wait 2 seconds to abort both requests
setTimeout(() => controller.abort(), 2000);
Em seu artigo Busca abortávelJake Archibald detalha um bom utilitário para criar abortable fetches sem a necessidade de todo o boilerplate:
function abortableFetch(request, opts) {
const controller = new AbortController();
const signal = controller.signal;
return {
abort: () => controller.abort(),
ready: fetch(request, { ...opts, signal })
};
}
Para ser totalmente honesto, não estou muito animado com o método de cancelamento de fetches. Em um mundo ideal, um .cancel() básico sobre a Promessa retornada por uma busca seria legal, mas há problemas que também viriam com isso. De qualquer forma, estou entusiasmado com a possibilidade de cancelar o fetch e o senhor também deveria estar!