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 o signal
  • Chame o AbortController‘s abort 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!