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);
复制代码

 

 

 

 

 

 

 

 

 

 

 

 

posted @   古墩古墩  Views(407)  Comments(0Edit  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
历史上的今天:
2019-05-26 vue中单选框与多选框的实现与美化
2019-05-26 bootstrap单选框复选框的使用
点击右上角即可分享
微信分享提示