阅读 95

axios切断请求CancelToken;外部控制promise返回

有时候我们需要对一些请求做出拦截,不让继续请求。

情景:当同样的接口连续请求时,我们可以把前面的请求在还未响应时,切断。

今天发现有人将请求接口写在了循环里,并且实现了一个功能,很是窝火。因为我认为把接口放在循环里是不对的,说不出哪不对,它就是不对。

近期做了axios请求切断。导致了这个功能失效。

记录一下:如何在拦截器切断统一请求。

我们封装了request请求拦截器,所以在拦截器里实现切断就可以了。

// 取消还未完成的同请求
let pending = [];
let cancelToken = axios.CancelToken;
let removePending = config => {
  for (let p in pending) {
    if (pending[p].u === config.url + "&" + config.method) {
      //当前请求在数组中存在时执行函数体
      pending[p].f(); //执行取消操作
      pending.splice(p, 1);
    }
  }
};

上面这段代码 先声明了 一个队列;然后定义一个取消请求的方法;

用队列中每一项的 u属性和 请求的url+method方法做对比,若两者一样,代表是统一个请求。然后执行f方法(切断请求)。再删除队列中的这一项。

 

什么时候,想队列中添加数据呢?

在,请求拦截器中:

    removePending(config);
    config.cancelToken = new cancelToken(c => {
        // 这里的axios标识是用请求地址&请求方式拼接的字符串
        pending.push({ u: config.url + "&" + config.method, f: c });
    });

在每次请求拦截器中先执行一次拦截的方法,如果条件匹配,则取消请求。如果没有取消本次请求,则执行请求拦截器后面的逻辑。

紧接着是,给config对象加一个canceltoken对象。new cancelToken的回调函数的第一个参数c,就是切断请求的方法。

可见,队列中的每一项,记录了本次请求的一个u:uuid,用于识别本次请求的id。这里用url和请求方法拼接成的。有一个弊端是,如果两次请求的参数不一样,同样会识别成同一请求。解决方法是:1、指定一个属性,控制某些请求不切断,或在u属性上加上参数值,参数值不同,就不会识别成 同一请求。

 

为了测地拦截重复请求,我们可以在响应拦截器中同样执行一次切断方法:

removePending(response.config);

 

以上做法有什么好处?

当有很多方法并行请求时,对服务器会产生压力。如果能够取消相同的请求,就会减轻服务器压力。

 

axios的cancelToken原理是什么呢?

其实是用一个外部变量 接受住了promise的resolve方法。从而可以在外部控制promise的执行。resolve传递出一个值,比如是cancel时,执行ajax的abort方法。从而取消请求。

来一个外部控制promise的例子:

let outResolve,count = 0;
let a = function (){
    return new Promise(resolve => {
        outResolve = resolve;
        setTimeout(() => {
            outResolve("111")
        },5000);
    })
}

a().then(res => {
    console.log(res);//正常5s后会返回结果,但是由于下面的方法,在第2s时,提前结束了promise
})
let timer = setInterval(() => {
    count += 1;
    console.log(count);
    if(count == 2){//执行这个代码会在第二秒提前执行promise的resolve方法
        outResolve("外部截断promise")
        clearInterval(timer)
    }
}, 1000);

 

 

 

 

 

 

 

 

 

 

 

 

原文:https://www.cnblogs.com/fqh123/p/14815441.html

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐