This is the 21st day of my participation in Gwen Challenge

The origin of

A page needs to download all the data function, download a large amount of data, long interface delay…..

The initial data amount of a page loading is prolonged, but the single retrieval is fast. When the initial data loading occurs, the retrieval interface returns, and the subsequent returns of the initial data cover the display of the retrieved data….

These situations require us to:

  1. Can manually cancel/terminate Request Request.
  2. Some page interfaces can only have one request on at a time.

The status quo

The system is based on the secondary development of vue-element-admin, which is open source of Elder brother’s Underwear. The request is made by AXIos, and the key code of request.js is as follows:

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  withCredentials: true.// send cookies when cross-domain requests
  timeout: 500000.// request timeout
  transformRequest: [function(data) {
    // Perform any conversion on data
    returnQs.stringify({ ... data },// Array conversion
    { arrayFormat: 'brackets'}})})// request interceptor
service.interceptors.request.use(
  config= > {
    // do something before request is sent

    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      config.headers['token'] = getToken()
    }
    return config
  },
  error= > {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
Copy the code

How to initiate a request:

export function remoteApi(data) {
  return request({
    url: '/api'.method: 'post',
    data
  })
}
Copy the code

Cancels the request cancelToken

Its official documentation: Cancel:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // Processing error}}); axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// Cancel the request (the message argument is optional)
source.cancel('Operation canceled by the user.');
Copy the code

Modified request method

export function remoteApi(data, cancelToken) {
  return request({
    url: '/api'.method: 'post',
    cancelToken,
    data
  })
}
Copy the code

When the actual request is made, cacelToken is created:

// inside the component method
this.cancelToken = CancelToken.source()
remoreApi(data, this.cancelToken).then(....) .catch(....) .finally(....)Copy the code

To cancel the request, execute:

// inside the component method
this.cancelToken.cancel('Cancel download')
Copy the code

Avoid repeated requests

To avoid repeated requests from one interface, the data returned by the interface with a long delay may overwrite the data returned by the other interface, resulting in data display errors. The idea is relatively simple, using a global Map to store the request identity and corresponding cancelToken. Before the request is made, the cancellation method corresponding to cancelToken is invoked according to the request identifier, and then a new request is made to satisfy the condition.