基于fetchAPI封装newFetch方法,实现请求超时/错误
2020-10-28 本文已影响0人
昊哇恰
- 知识点
- 阻断请求方法
-
AbortController
控制器,可以阻断web请求
// IE不支持 const controller = new AbortController() // AbortController.signal属性获取其关联 AbortSignal对象的引用 const signal = controller.signal controller.abort()
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')
- 个人理解 写的不对的地方希望大家指出,谢谢。
- 阻断请求方法