vue axios 取消请求,记录

根据文档做出一个全局统一处理的请求取消 https://www.runoob.com/vue2/vuejs-ajax-axios.html,这里第二种方法,直接获取cancel方法,然后直接执行cancel方法

1.main.js

Vue.prototype.Cancel = [];

在vue原型上声明一个全局变量 cancel用来保存在请求时的cancel方法

2.统一请求拦截封装 http.js

let http = axios.create({
  timeout: 15000,
  headers: {
    'Content-Type' : 'application/json;charset=UTF-8'
  },
});
let _this = Vue.prototype;
// 请求拦截
http.interceptors.request.use(config => {
  // console.log("请求信息:")
  // console.log(JSON.stringify(config))
  config.cancelToken = new axios.CancelToken(function (cancel) {
    _this.Cancel.push(cancel);
  });

请求拦截里获取请求时的cancel,添加到Cancel数组中

3.router.js

Vue.prototype.Cancel && Vue.prototype.Cancel.forEach(cancel => {
    console.log(cancel)
    cancel();// 执行cancel方法关闭请求
  });
  Vue.prototype.Cancel = [];

当路由变化时 遍历Cancel数组,执行cancel方法,然后清空数组

4.http.js响应拦截

  return Promise.resolve(response)
}, error => {
  // console.log("错误信息:")
  // console.log(JSON.stringify(error))
  if (axios.isCancel(error)) { // 如果是取消请求抛出的错误,终止Promise调用
    _this.$closeLoad();
    return new Promise(() => {});
  }

在响应拦截中的错误里对取消请求抛出的错误终止promise调用链

5.axios的取消请求源码

'use strict';
var Cancel = require('./Cancel');
function CancelToken(executor) {
     if (typeof executor !== 'function') {
         throw new TypeError('executor must be a function.');
     }
     var resolvePromise;
    this.promise = new Promise(function promiseExecutor(resolve) {
         resolvePromise = resolve;
     });
     var token = this;
     executor(function cancel(message) {
         if (token.reason) {
         // Cancellation has already been requested
             return;
         }
         token.reason = new Cancel(message);
         resolvePromise(token.reason);
     });
}
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
    if (this.reason) {
         throw this.reason;
     }
};
CancelToken.source = function source() {
     var cancel;
     var token = new CancelToken(function executor(c) {
         cancel = c;
     });
     return {
         token: token,
     cancel: cancel
     };
};
module.exports = CancelToken;

分析:

1.CancelToken这个类初始化的时候需要传递一个executor参数,而且executor必须是一个function,在这个类的内部还创建了一个promise,并且分离了reslove,把控制权又交给了executor的执行体上

2.source这个方法中定义了一个变量cancel,并且在这个方法内new了一个CancelToken,传入一个参数c,然后将c赋值给了cancel,同样的是把executor方法的变量c的控制权给了cancel,而c又是在初始化CancelToken时传入的executor方法,既是上面代码中的

function cancel(message) {
         if (token.reason) {
         // Cancellation has already been requested
             return;
         }
         token.reason = new Cancel(message);
         resolvePromise(token.reason);
     }

也就是把上面这个方法赋值给了source方法中cancel属性,通过cancel可以控制CancleToken的promise对象,source方法中token属性是一个CancelToken实例,同样可以访问到CancelToken的promise对象

所以CancelToken目的是为了能够分离promise和resolve方法,让用户可以自主调用resolve,一旦resolve后就会触发promise的then方法,下面是then方法里代码,当进入then后会立即调用abort()原生方法取消请求,同时调用reject让外层的promise的失败

if (config.cancelToken) {
    // Handle cancellation
    config.cancelToken.promise.then(function onCanceled(cancel) {
        if (!request) {
            return;
        }
        request.abort();
        reject(cancel);
        // Clean up request
        request = null;
    });
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值