js - 取消接口请求


js - 取消接口请求

axios - cancelToken

参考资料

axios


axios中断请求cancelToken

use

CancelToken.source

可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

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

axios.get('/user/12345', {//get请求在第二个参数
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 处理错误
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token//post请求在第三个参数
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

构造函数

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// cancel the request
cancel();

notice

  1. 可以使用同一个 cancel token 取消多个请求
  2. source.cancel函数执行后,会永久取消请求(如何取消拦截?)
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {//get请求在第二个参数
  cancelToken: source.token // 1. 使用同一个 cancel token 取消多个请求
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 处理错误
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, { //post请求在第三个参数
  cancelToken: source.token // 1. 使用同一个 cancel token 取消多个请求
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.'); // 2. source.cancel函数执行后,会永久取消请求

如何取消拦截

使用构造函数创建 cancel token,每次请求使用不同的 cancel token,请求前执行前一个cancel token

eg:重复请求只执行最后一次




重复点击问题***

开发的时候会遇到一个重复点击的问题,短时间内多次点击同一个按钮发送请求会加重服务器的负担,消耗浏览器的性能,多以绝大多数的时候我们需要做一个取消重复点击的操作

axios拦截器

    import axios from 'axios';
    
    axios.defaults.timeout = 5000;
    axios.defaults.baseURL ='';

    let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
    let cancelToken = axios.CancelToken;
    let removePending = (ever) => {
        for(let p in pending){
            if(pending[p].u === ever.url + '&' + ever.method) { //当当前请求在数组中存在时执行函数体
                pending[p].f(); //执行取消操作
                pending.splice(p, 1); //把这条记录从数组中移除
            }
        }
    }
    
    //http request 拦截器
    axios.interceptors.request.use(
    config => {
      config.data = JSON.stringify(config.data);
      config.headers = {
        'Content-Type':'application/x-www-form-urlencoded'
      }
      // ------------------------------------------------------------------------------------
      removePending(config); //在一个ajax发送前执行一下取消操作
      config.cancelToken = new cancelToken((c)=>{
         // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
         pending.push({ u: config.url + '&' + config.method, f: c });  
      });
      // -----------------------------------------------------------------------------------------
      return config;
    },
    error => {
      return Promise.reject(err);
    }
  );
  //http response 拦截器
  axios.interceptors.response.use(
    response => {
      // ------------------------------------------------------------------------------------------
      removePending(res.config);  //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
      // -------------------------------------------------------------------------------------------
      if(response.data.errCode ==2){
        router.push({
          path:"/login",
          querry:{redirect:router.currentRoute.fullPath}//从哪个页面跳转
        })
      }
      return response;
    },
    error => {
      return Promise.reject(error)
    }
  )

原生js - abort()