web应用开发中怎样防止重复请求
Admin 2022-07-05 群英技术资讯 1806 次浏览
这篇文章主要讲解了“web应用开发中怎样防止重复请求”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web应用开发中怎样防止重复请求”吧!我们在web应用开发过程当中,经常会遇到一个时刻发起了多个请求的场景

我们的项目中,目前大部分情况也是采用以上两种方式做的。今天来介绍一个新的方式。
我们之前实例化一个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的缓存
}
}
就像操作定时器一样,要先尝试取消上一次,然后再开启下一次
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)
}

控制台也没有任何报错啦。(后续完善到项目中)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要给大家介绍了关于如何使用原生Js实现随机点名的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Node.js 调试 的方式有什么,怎样调式方便?对于Node 代码调式,很多朋友只会用console.log 这种带有侵入性的方法,但是其实Node.js 也可以做到跟浏览器调试一样的方便的,对此本文给大家分享两种常见的 Node.js 的方式,需要的朋友可以参考了解看看。
javascript改变图片链接地址的方法:【window.onload = function () {ImageSrc();} function ImageSrc() { var imgs = document.getEleme...】。
JS有哪些高效的魔法运算符?对于JS运算符大家应该都比较熟悉,但JavaScript在不断更新,也会增加不少高效的运算法,这篇文章给大家分享一些高效的魔法运算符,感兴趣的朋友就继续往下看吧。
这篇文章主要为大家详细介绍了JavaScript+html实现前端页面滑动验证,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008