美文网首页
基于fetchAPI封装newFetch方法,实现请求超时/错误

基于fetchAPI封装newFetch方法,实现请求超时/错误

作者: 昊哇恰 | 来源:发表于2020-10-28 17:28 被阅读0次
    • 知识点
      • 阻断请求方法
        1. AbortController 控制器,可以阻断web请求
            // IE不支持
           const controller = new AbortController()
            // AbortController.signal属性获取其关联 AbortSignal对象的引用
           const signal = controller.signal
           controller.abort()
          
        2.兼容ieXMLHttpRequest.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