为什么?
题目:为什么axios要配置AbortController?防抖节省不行吗?
分析:
- 防抖节省本质上是用延时器来操作哀求的。
- 防抖是判断延时器是否存在,假如存在,扫除延时器,重新开启一个延时器,只执行最后一次哀求。
- 节省呢,是判断延时器是否存在,假如存在,直接return掉,直到执行完这个延时器。
- 事实上,这些体验感都不算友好,由于对于用户来说,得等一些时间,尤其是首次哀求,不是那么流畅。
- 而当我们配置了AbortController,就可以停止掉重复的哀求,而且首次不需要等待时间,好坏常友好的举动。
- 从axios0.22.0开始,开始支持AbortController,而且废弃CancelToken。之以是我们不用CancelToken来取消哀求,是由于CancelToken存在内存走漏隐患,并不安全,以是官方人员盼望用户们升级版本,利用AbortController镌汰内存走漏风险。
- 事实上,凡事用xhr封装的哀求库,都可以配置AbortController,如fetch,axios,alova等等
- 本文封装的原理可以移步至另一篇博客检察:如何避免接口重复哀求(axios保举利用AbortController)-CSDN博客
前置条件:
升级axios至最新版本。由于AbortController是从0.22.0开始支持的。假如你的版本已经在0.22.0以上,可以正常利用,不升级亦可。
以笔者升级的项目为例,我这里的版本是很古老的0.18.0,以是我这里是直接把axios升级至现在最新的稳定版本1.7.2。(假如升级失败,可以先移除掉axios,再重新安装。)
- //安装axios
- npm i axios
- //卸载axios
- npm uninstall axios
复制代码 接入步骤:
1.在封装axios的全局文件中,先定义两个变量
- 在全局封装axios的request.js文件的全局里定义两个变量
- isCancel 用来判断请求是否被取消
- cacheRequest 用来存储需要取消重复请求的接口
复制代码- // isCancel-取消标识 可以根据这个值判断请求是否被取消
- const { isCancel } = axios
- const cacheRequest = {}
复制代码 2.定义一个函数,用来取消哀求和删除cacheRequest里对应的哀求
- // 删除缓存队列中的请求
- function abortCacheRequest(reqKey) {
- if (cacheRequest[reqKey]) {
- // 通过AbortController实例上的abort来终止请求
- cacheRequest[reqKey].abort()
- delete cacheRequest[reqKey]
- }
- }
复制代码 3.在哀求拦截器里加入取消重复哀求的逻辑
之以是做成根据isAbort标识判断是否利用AbortController,是由于并不是全部的哀求都是需要取消重复哀求的,就像并不是全部的哀求都需要防抖节省一样,以是当我们有需要的时候,再加这个标识就好。
- const service = axios.create({
- baseURL: hosts.server, // api 的 base_url
- timeout: 50e3, // request timeout
- });
- service.interceptors.request.use(config => {
- // isAbort - 是config里配置的是否清除相同请求的标识,不传则默认是不需要清除
- const { url, method, isAbort= false } = config
- if (isAbort) {
- // 请求地址和请求方式组成唯一标识,将这个标识作为取消函数的key,保存到请求队列中
- const reqKey = `${url}&${method}`
- // 如果config传了需要清除重复请求的isAbort,则如果存在重复请求,删除之前的请求
- abortCacheRequest(reqKey)
- // 将请求加入请求队列,通过AbortController来进行手动取消
- const controller = new AbortController()
- config.signal = controller.signal
- cacheRequest[reqKey] = controller
- }
- })
复制代码 4.在相应拦截器里加入判断
假如哀求成功后,扫除cacheRequest里对应的存储;而且在error里判断,取消的哀求不做任何处理
- service.interceptors.response.use(res => {
- // 请求成功,从队列中移除
- const { url, method, isAbort = false } = response.config
- if (isAbort) delete cacheRequest[`${url}&${method}`]
- }), error => {
- if (isCancel(error)) {
- // 通过AbortController取消的请求不做任何处理
- return Promise.reject({
- message: '重复请求,已取消'
- })
- }
- }
复制代码 5.利用
在调用接口的时候,增加一个isAbort的标识为true就能开启取消重复哀求的功能了
- //请求示例
- export function getList(data) {
- return request({
- url: '/list',
- method: 'post',
- data: data,
- isAbort: true // 配置标识 如果该接口频繁请求 则会中断上次请求保留最新一次请求
- })
- }
复制代码 效果图:
体验感极佳,status为canceled,都是被取消的哀求
小拓展:
如何取消xhr的哀求:
如何取消fetch哀求:
- let controller = new AbortController();
- let signal = controller.signal;
- fetch(url, {signal});
- controller.abort(); // 取消请求
- //监听请求取消情况
- signal.addEventListener('abort',
- () => console.log('abort!',signal.aborted)
- );
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |