温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

项目中如何使用axios过滤多次重复请求

发布时间:2021-07-07 17:21:16 来源:亿速云 阅读:442 作者:chen 栏目:开发技术

这篇文章主要讲解了“项目中如何使用axios过滤多次重复请求”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“项目中如何使用axios过滤多次重复请求”吧!

目录
  • 一、前言:

    • 这个情况下,我们通常的做法有两种:

  • 二、CancelToken类

    • 最终效果


一、前言:

我们在web应用开发过程当中,经常会遇到一个时刻发起了多个请求的场景

项目中如何使用axios过滤多次重复请求

这个情况下,我们通常的做法有两种:

  • 可以在请求时show一个loading,阻止用户操作。

  • 或者人为加个变量,做一个请求的节流

我们的项目中,目前大部分情况也是采用以上两种方式做的。今天来介绍一个新的方式。

二、CancelToken类

我们之前实例化一个Promise,这个对象是否成功与否,是无法在函数外部决定的,这里边使用要用到一个小窍门,可以让一个promise 和resolve分离。任何时机都可以触发resolve:

  // 一个promise   let resolvePromise   let p = new Promise((resolve, reject) => {     resolvePromise = resolve   })   // 这样在外部执行   resolvePromise()

ok,有了这个前提,我们需要借助axios.CancelToken这个类。

这个类相当于在每次请求的时候开启另一个promise和当前的请求形成一个promise.race(请求p1,取消请求p2),在promise中的resolve方法赋值给了一个外部的变量去接收。我们可以根据需求,人为决定是否取消前次请求。其实这就类似,原来我们写fetch封装接口超时的Promise.race类似。

cancelToken中也提供了相应的static方法source用来生成一个cancelToken和一个cancel方法其实就是这个promise的一个resolve。

CancelToken.source = function source() {     var cancel;     //      var token = new CancelToken(function executor(c) {         cancel = c;     });     return {         token: token,         cancel: cancel,     };

根据我们常用的的缓存方式,我们可以声明一个map来存储每次请求的url,同时存储对应的cancel方法。

// 声明一个全局map     const pendingHttp = new Map()     // axios中内置的CancelToken类     const CancelToken = axios.CancelToken             function addApi (config) {       config.cancelToken = new CancelToken((cancel) => {         const url = config.url         console.log(pendingHttp)         if (!pendingHttp.has(url)) {           pendingHttp.set(url, cancel)         }       })     }     function cancelApi (config) {       const url = config.url       if (pendingHttp.has(url)) { // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除         const cancel = pendingHttp.get(url)         cancel(url + '取消了')         pendingHttp.delete(url) // 清空当前url的缓存       }     }
  • 要特殊注意,要想取消掉一个请求,需要在config上添加cancelToken这个属性赋值为CancelToken的实例。否则cancel不掉。

就像操作定时器一样,要先尝试取消上一次,然后再开启下一次

httpService.interceptors.request.use(config => {       cancelApi(config)       addApi(config)              // 本地调试的时候,是跨域的情况,加请求头会有限制(此处是项目代码无关紧要)       const { headers = {} } = config; const { globalObj = {} } = window       Object.assign(headers, globalObj, { from })              return config     }, error => {       console.log(error)       return Promise.reject(error)     })

然后还有一种可能性,第一次请求已经返回了,又发起了相同的一次请求,所以在response里边也要cancelApi一下。

httpService.interceptors.response.use(       response => {         cancelApi(response.config)         sentryCatchApi(response)       },       error => {         // 请求超时         if (error.message.includes('timeout')) { // 判断请求异常信息中是否含有超时timeout字符串           Toast.error({ text: '网页请求超时,请刷新重试~' })         }         sentryCatchApi(error)         return Promise.reject(error)       }     )

我们需要注意一点,cancel其实就是resolve,我们cancel执行时候传入的参数,会最终在response的error回调中,作为参数返回,这样我们的捕捉错误的方法可能会有报错。

// 假设我们的error方法是这样封装的。 来看一下sentryCatchApi     error => {       sentryCatchApi(error)       return Promise.reject(error)     }   // 由于这个方法需要接收一个对象,但是我们cancel取消请求的情况下,返回的是一个字符串,这时就报错了。   function sentryCatchApi (res) {       try {         res = res || {}         const resData = res.data || {}         Sentry.captureException(JSON.stringify(resData))         console.log(`           获取数据失败:           请在浏览器中打开进入 webview的地址,并粘贴出来,便于问题排查           :接口相关信息:           接口地址:${res.config.url},           接口返回值:code:${resData.code},           message:${resData.message},           data:${JSON.stringify(resData.data)}         `)       } catch (err) {         console.error(err)       }     }

需要使用isCancel这个api

   error => {     if (axios.isCancel(error)) return console.log('请求被取消了', error.message)     sentryCatchApi(error)     return Promise.reject(error)   }

最终效果

项目中如何使用axios过滤多次重复请求

控制台也没有任何报错啦。(后续完善到项目中)

感谢各位的阅读,以上就是“项目中如何使用axios过滤多次重复请求”的内容了,经过本文的学习后,相信大家对项目中如何使用axios过滤多次重复请求这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI