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
AbortController
instância - Essa instância tem um
signal
propriedade - Passe o
signal
como uma opção de busca para osignal
- Chame o
AbortController
‘sabort
para 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!