This is the 7th day of my participation in Gwen Challenge

When switching steps or switch TAB, etc., before a component by the request may also in the works, the user has pulled out of the step process, also may be switched to the other TAB page, before the request is in progress, if not to deal with the request of the unfinished, will greatly influence the reliability of the page, and even lead to subsequent requests timeout, Or data processing is incorrect, page presentation is incorrect and so on

For questions like these, we need to know how to cancel the request

The official sample

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // The executor function takes a cancel function as an argumentcancel = c; })});// cancel the request
cancel();
Copy the code

The CancelToken method on Axios is instantiated in the request configuration. The return value of the callback function is the method that cancels the current request: cancel, which can be called at any time to cancel the request by simply saving cancel in one place

In real projects we tend not to use it as in the official website example, but more in the Axios interceptor for global configuration management, requiring some changes to the above code

Project implementation

The project uses Vuex and AXIos request and response interceptors. Instantiate cancelToken in the AXIos request interceptor and register the callback cancellation request method with Vuex with the request function name key and the cancellation request method val. This method can then be called with Vuex during the request period to cancel the request.

Axios interceptor

Vue state management mode: Vuex

Vuex

Add state, Actions, etc., to the relevant modules configuration in the Store folder

const state = {
  cancel: {},}const mutations = {
  CANCEL(state, { funNames = [], msg = "User manually cancels network request" }) {
    if (!Object.keys(state.cancel).length) {
      return false
    }
    for (const key in state.cancel) {
      if (state.cancel.hasOwnProperty(key)) {
        if (funNames.includes(key)) {
          if(! state.cancel[key].response) { state.cancel[key].cancel(msg); state.cancel[key].response =true; }}}else {
        return false}}},SET_CANCEL(state, { cancel, funName }) {
    state.cancel[funName] = { cancel, response: false };
  },
  RESPONSE(state, funName) {
    if (Object.keys(state.cancel).includes(funName)) {
      state.cancel[funName].response = true; }}},const actions = {
  setCancel({ commit }, fn){
    commit('SET_CANCEL', fn)
  },
  response({ commit }, res){
    commit('RESPONSE', res)
  },
  cancel({ commit }, res) {
    commit('CANCEL', res)
  }
}

Copy the code

Axios

Configure cancel related intercept processing in the interceptor

import axios from "axios";
import store from "@/store";

var instance = axios.create({
  timeout: 30000.withCredentials: true
});

const CancelToken = axios.CancelToken;

// Request interception
instance.interceptors.request.use(
  req= > {
    req.cancelToken = new CancelToken(cancel= > {
      let url = req.url
      let str = url.split('/')
      str = Array.from(new Set(str))
      let index = str.length - 1
      let funName = str[index]
      store.dispatch("setCancel", { cancel, funName: funName })
    });
    return req;
  },
  err= > Promise.reject(err)
);

// Response interception
instance.interceptors.response.use(
  function (response) {
    store.dispatch("response", response.config.funName);
    if (response.status === 200 && response.data.request_id) {
      if (response.data.code == 0) {
        return response.data;
      } else {
        let msg = response.data.msg
        Message.error({
          message: msg,
          duration: 3000.center: true.offset: 50.showClose: true
        });
        return Promise.reject(error); }}return response;
  },
Copy the code

call

Once configured, it can be called in the desired business method

FunNames Sets the request API name to cancel so that you can cancel one or more outgoing requests at the same time

handleCancel() {
    this.$store.dispatch("cancel", { funNames: ["flavors"."transerver_info"]})}Copy the code

Give it a try