文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

浅谈axios中取消请求及阻止重复请求的方法

2024-04-02 19:55

关注

前言

在实际项目中,我们可能需要对请求进行“防抖”处理。这里主要是为了阻止用户在某些情况下短时间内重复点击某个按钮,导致前端向后端重复发送多次请求。这里我列举两种比较常见的实际情况:

以上情况有可能在有Loading遮罩时依然发生,所以我们要考虑前端阻止重复请求的方法。

核心——CancelToken

在Axios中取消请求最核心的方法是CanelToken。在官网文档中有写到两种方法使用CancelToken,这里简单粘贴出来,并增加了注释

方法1:


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

axios.get('/user/12345', {
  // 必须对请求进行cancelToken设置
  cancelToken: source.token
}).catch(function (thrown) {
  // 如果请求被取消则进入该方法判断
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

// 取消上面的请求
// source.cancel('messge') message为可选项,必须为String
source.cancel('Operation canceled by the user.');

方法2:


const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  // 在options中直接创建一个cancelToken对象
  cancelToken: new CancelToken(function executor(c) {
    cancel = c;
  })
});

// 取消上面的请求
cancel();

实际应用和封装

上文已对axios中的核心方法进行了举例,但是在实际中我们往往不会像官网例子中那样使用,更多的是在axios的拦截器中做全局配置管理。这样的话我们需要对上面的代码进行一些改变。

这里说一下我实现的大体思路:

思路说完,我们直接上代码


// 正在进行中的请求列表
let reqList = []


const stopRepeatRequest = function (reqList, url, cancel, errorMessage) {
  const errorMsg = errorMessage || ''
  for (let i = 0; i < reqList.length; i++) {
    if (reqList[i] === url) {
      cancel(errorMsg)
      return
    }
  }
  reqList.push(url)
}


const allowRequest = function (reqList, url) {
  for (let i = 0; i < reqList.length; i++) {
    if (reqList[i] === url) {
      reqList.splice(i, 1)
      break
    }
  }
}

const service = axios.create()

// 请求拦截器
service.interceptors.request.use(
  config => {
 let cancel
   // 设置cancelToken对象
    config.cancelToken = new axios.CancelToken(function(c) {
     cancel = c
    })
    // 阻止重复请求。当上个请求未完成时,相同的请求不会进行
    stopRepeatRequest(reqList, config.url, cancel, `${config.url} 请求被中断`)
    return config
  },
  err => Promise.reject(err)
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 增加延迟,相同请求不得在短时间内重复发送
    setTimeout(() => {
      allowRequest(reqList, response.config.url)
    }, 1000)
    // ...请求成功后的后续操作
    // successHandler(response)
  },
  error => {
    if (axios.isCancel(thrown)) {
      console.log(thrown.message);
    } else {
      // 增加延迟,相同请求不得在短时间内重复发送
      setTimeout(() => {
        allowRequest(reqList, error.config.url)
      }, 1000)
    }
    // ...请求失败后的后续操作
    // errorHandler(error)
  }
)

一些小细节

为什么没用前文方法2中的代码进行cancelToken设置?
axios的文档中有一条备注:

Note: you can cancel several requests with the same cancel token.
你可以使用相同的Token来取消多个请求

所以我不想在每个请求前都new一个新的对象
请务必使用方法2,保证每次cancel都能正确执行。之前方法会导致当出现cancel后,后续请求也会持续cancel

为什么在response中需要增加延迟?
因为不想让用户在极短的时间内重复进行相同请求。
请注意,在response中阻止请求和在request中的阻止请求是两个概念:
request中是阻止上个请求 未完成 时又开始了相同的请求
response中是阻止上个请求 完成后 一段时间内不允许相同请求

我能否在cancel时传递一个对象,而不仅仅是message?
以官方提供的接口来看是不可以的,你可以仿照官方源码进行重新封装,或者使用第三方插件,或者使用另一个方法:将对象转换为JSON字符串,然后在需要的地方再转换回来

到此这篇关于浅谈axios中取消请求及阻止重复请求的方法的文章就介绍到这了,更多相关axios中取消请求及阻止重复请求内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯