基于fetchAPI封装newFetch方法,实现请求超时/错误
作者:
昊哇恰 | 来源:发表于
2020-10-28 17:28 被阅读0次
- 知识点
- 阻断请求方法
-
AbortController
控制器,可以阻断web请求
// IE不支持
const controller = new AbortController()
// AbortController.signal属性获取其关联 AbortSignal对象的引用
const signal = controller.signal
controller.abort()
2.兼容ie
的XMLHttpRequest.abort()
-
Promise.race([])
- 同时发送多个请求,返回最先请求到的结果
- 问题: 当我们重传的时候,如果不终止上一次请求。上次请求依然执行
- 代码
let newFetch = (url) => {
// 重传次数控制
let requestAgain = 0
// 创建控制器对象
const controller = new AbortController()
// AbortController.signal属性获取其关联 AbortSignal对象的引用
const signal = controller.signal
//判断是否为IE 该判断不支持IE11 以上
if (navigator.userAgent.indexOf('MSIE') > -1) {
// 如果是ie 不支持-- AbortController--
// 也不支持fetch
// 此时使用原生xmlHttpRequest
// ie5/6和ie6+创建xmlHttpRequest对象有所不同
return new Promise((resolve, reject) => {
xmlreq(url, 'GET', resolve)
}).then((res) => {
// console.log('success')
// console.log(res)
}).catch(err => {
// 重新发送请求一次
if (requestAgain != 0) return
requestAgain++
xmlreq(url, 'GET', resolve)
})
} else {
// 不是ie
return Promise.race([requestPromise(url, signal).then(async (res) => {
let result = await res.json()
// console.log(result)
}).catch((err) => {
// 错误时重发
// 使用控制器终止请求
controller.abort()
// 重新发送请求
requestPromise(url).then(async (res) => {
let result = await res.json()
// console.log('请求重发')
// console.log(result)
})
}), new Promise((resolve, reject) => {
setTimeout(() => {
// 使用控制器终止请求
controller.abort()
// 重新发送请求一次
if (requestAgain != 0) return
requestAgain++
requestPromise(url).then(async (res) => {
let result = await res.json()
// console.log('请求重发')
// console.log(result)
})
}, 30000);
})])
}
}
// 封装fetch 请求
let requestPromise = (url, signal = {}) => {
return fetch(url, {
signal,
headers: {
"Content-Type": 'application/json;charset=utf-8;'
}
})
}
// 封装xmlHTTPRequest
let xmlreq = (url, methods = 'GET', resolve) => {
// 创建xmlHttpRequest 对象
let xmlHttpReq
if (window.XMLHttpRequest) {
// ie6+
xmlHttpReq = new XMLHttpRequest();
} else {
// ie5/6
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP")
}
// 设置超时时间
xmlHttpReq.timeout = 30000
xmlHttpReq.open('GET', url)
xmlHttpReq.send()
xmlHttpReq.ontimeout = (event) => {
// 终止上一次请求
xmlHttpReq.abort()
// 重新发送请求
xmlHttpReq.send()
}
xmlHttpReq.onreadystatechange = function (event) {
if (event.target.readyState == 4 && event.target.status == 200) {
let resData = JSON.parse(xmlHttpReq.response)
resolve(resData)
}
}
}
newFetch('http://a.com')
本文标题:基于fetchAPI封装newFetch方法,实现请求超时/错误
本文链接:https://www.haomeiwen.com/subject/rpdcvktx.html
网友评论