How to cancel/interrupt a request made with Axios?

Asked

Viewed 375 times

5

Generally, I usually make some AJAX calls with the library Axios.

Those days I needed a resource, where I could interrupt a certain request already started, but did not know how to do.

Is there any way to end a request started with Axios?

For example, I have a file api.js with some default settings.

import axios from 'axios';

const api = axios.create({
    baseURL: process.env.VUE_APP_API
});


api.interceptors.request.use((config) => {

    let token = window.localStorage.getItem('token');

    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }

    return config;
})

export default api;

I make my calls with Axios like this:

import api from "./api";

async function obterUsuarios() {
   const {data: usuarios} = await api.get('usuarios');

   return usuarios;
}


const usuarios = await obterUsuarios();

Doubts:

  • It is possible to cancel a call axios through the Promise returned by the same?

  • It is possible to cancel the request even using await?

  • It is possible to cancel an Axios call through Promise returned by the same? that part got weird, a promisse has not yet been executed? or?

  • @novic "... through Promise returned by Next" was just not to repeat

1 answer

5


As the interface name says, a promise cannot be broken. So, by itself, Promises are not cancellable in Javascript.

However, the Axios offers a request cancellation mechanism.

Basically, you need to create a cancellation token and passes to the request builder. Something like this:

const CancelToken = axios.CancelToken;

// Criamos a origem do token de cancelamento:
const cancelTokenSource = CancelToken.source();

axios.get('/path/of/request', {
  // Passamos o token de cancelamento para o construtor da requisição:
  cancelToken: cancelTokenSource.token
});

// Note que a chamada acima retorna uma promessa.

Note that cancelTokenSource (returned by the application of CancelToken.source) owns a property token (which is the token cancellation), but also has a method cancel, which should be used to cancel the request. You can use it by passing a reason for the cancellation:

cancelTokenSource.cancel('Não é mais de meu interesse enviar esta requisição.');

Since the cancel is invoked, the Promise that the request constructor returns will be rejected. You can then use the catch to treat this rejection:

axios.get('/path/of/request', {
  // Passamos o token de cancelamento para o construtor da requisição:
  cancelToken: cancelTokenSource.token
}).catch(function (thrown) {
  // Utilizamos o método `isCancel` para saber se o erro da rejeição veio de um cancelamento:
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // Trate o erro.
  }
});

As the rejection is notified through the rejection of the promise, there is no problem in treating it with async/await:

async function doRequest() {
  try {
    const response = axios.get('/path/of/request', {
      // Passamos o token de cancelamento para o construtor da requisição:
      cancelToken: cancelTokenSource.token
    });

    // Faça algo com `response`.
  } catch (thrown) {
    if (axios.isCancel(thrown)) {
      console.log('Request canceled', thrown.message);
    } else {
      // Trate o erro.
    }
  }
}

Like cancelTokenSource is "outside the request", you can cancel the operation from anywhere. Just be careful not to use the same token for more than one request, otherwise token can cancel all requests it was used at the same time.

If the request is canceled, as we have seen above, the promise that the request constructor (such as axios.get or axios.post) return is, by guarantee, rejected. This means that once you cancel an Axios request, the promise will never be resolved.

There is no explicit mention of this Axios documentation, but once the request is cancelled (using cancelTokenSource.cancel()), it is, in fact, aborted. This behavior is proven by the library’s own source code. See the implementation of abortion on adapter xhr (API of browsers) and in the adapter http (Node.js native module).


It’s a mechanism very similar to AbortController, which allows the cancellation of requests with the native API fetch.

  • 2

    Great explanation, but I got a question. It just cancels the wait for the answer, right? I mean, if the request has already arrived on the server and has not yet been answered, the Axios :)

  • 1

    @Rafaeltavares, I could not find any explicit information about what actually happens when it is canceled beyond the fact that the promise will be rejected. This means that it is guaranteed that once canceled, the Promise returned by the request constructor (such as axios.get) will be a rejected.

  • 1

    Taking a brief look at adapter source code xhr it is possible to notice that the request is actually aborted when it is executed cancel. The request is also aborted on adapter http (Node.js native module).

  • @Luizfelipe, I think I understand Rafael’s doubt. Because I have noticed, for example, that in an upload system that I have, the progress is displayed relative to what the frontend sends to the server. But when arriving at "100%", depending on the treatment done in the upload, the answer takes a lot (this is one thing is sending something else is what the server is doing with the upload). I don’t know if in such cases it could occur that the server could continue processing something even if it is canceled, but I also don’t think that this is a problem (depending on the case).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.