当前位置: 萬仟网 > IT编程>网页制作>CSS > fetch封装实例

fetch封装实例

2018年10月27日 02:08  | 萬仟网IT编程  | 我要评论

    【vue】fetch封装

    fetch 必然要替换 xmlhttprequest ,所以是时候尝试 fetch 了; 本封装仅针对npm引入; 本封装依赖 es6-promise 和 whatwg-fetch,分别对 promise 和 fetch 进行兼容性处理; 还有一种兼容性处理是依赖 es6-promise 和isomorphic-fetch ,但是看它的就会发现,isomorphic-fetch 只不过是引用了 whatwg-fetch ,并没有做二次开发,isomorphic-fetch 只是将fetch添加为全局,以便其api在客户端和服务器之间保持一致,所以没必要。

    封装的主要内容

    fetch 的请求方式同 $ajax 和 axios 都不太一样,并且它本身的get请求同其他请求对数据的处理和herder也不太相同,所以为了统一请求行为,方便请求过程,将请求过程进行封装; fetch 请求的结果均返回到.then()中,但是平时的习惯是是在 .then() 中处理正确结果,.catch() 中处理错误,所以对请求结果进行统一处理; fetch 本身没有 请求超时 这个概念,所以通过 promise.race 来处理,它的作用是多个promise同时运行,返回的结果以最快返回结果的那个promise的值为准。

    封装的代码

    // 处理promise和fetch的兼容性以及引入
    require('es6-promise').polyfill()
    import 'whatwg-fetch'
    
    // 前置拼接url
    const api = '***'
    
    // 自定义headers
    const headers = {
      'accept': 'application/json; version=3.13.0'
    }
    
    // 处理get请求,传入参数对象拼接
    const formaturl = obj => {
      const params = object.values(obj).reduce((a, b, i) => `${a}${object.keys(obj)[i]}=${b}&`, '?')
      return params.substring(0, params.length - 1)
    }
    
    /**
     * @param url    (string) 接口url
     * @param option (object) 参数对象,包括method(请求方式,不填默认'get'),headers(设置请求头,选填),data(请求参数,所有请求方式均适用)
     */
    const recofetch = (url, option = {}) => {
      // 设置请求超时的时间,默认10秒
      const timeout = option.timeout || 10000
    
      option.headers = option.headers || headers
      option.method = (option.method || 'get').tolocalelowercase()
    
      // 格式化get请求的数据(fetch的get请求需要需要将参数拼接到url后面)
      if (option.method === 'get') {
        if (option.data) {
          url = url + formaturl(option.data)
        }
      }
    
      // 对非get类请求头和请求体做处理
      if (option.method === 'post' || option.method === 'put' || option.method === 'delete') {
        option.headers['content-type'] = option.headers['content-type'] || 'application/json'
    
        // 非get类请求传参时,需要将参数挂在body上
        option.body = json.stringify(option.data)
    
        // 根据后台要求,如果有时候是java请求会用qs转
        // option.body = qs.stringify(option.data)
      }
      delete option.data
    
      return addtimeout(fetch(api + url, option), timeout)
    }
    
    // 对请求结果进行处理:fetch请求成功后返回的是json对象
    function parsejson (response) {
      return response.json()
    }
    
    // 
    /**
     * 增加超时处理:fetch本身是没有请求超时处理的,所以可以通过
     * @param fetchpromise (promise) fetch请求
     * @param timeout      (number)  请求超时的时间
     */
    function addtimeout (fetchpromise, timeout) {
      let timeoutfn = null
    
      // 请求超时的promise
      var timeoutpromise = new promise((resolve, reject) => {
        timeoutfn = function () {
          reject({
            code: 'timeout',
            text: '请求超时,请重试'
          })
        }
      })
    
      // 声明promise.race
      const racepromise = promise.race([
        fetchpromise,
        timeoutpromise
      ])
    
      settimeout(function () {
        timeoutfn()
      }, timeout)
    
      const racepromiseresult = new promise((resolve, reject) => {
        let status = 0
    
        racepromise
          .then(response => {
            status = response.status
            return response
          })
          .then(parsejson)
          .then(response => {
            // 将状态码添加到返回结果中,以备后用
            response.status = status
    
            // 如果返回码在300到900之间,将以错误返回,如果需要对错误统一处理,可以放在下面判断中
            if (/^[3-9]\d{2}$/.test(response.status)) {
              reject(response)
            }
    
            // 否则以正确值返回
            resolve(response)
          })
          .catch(error => {
            // 请求出错则报错 recofetch error: ***
            console.log('recofetch error:', error)
          })
      })
    
      // 将racepromise的结果返回
      return racepromiseresult
    }
    
    export default recofetch

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

◎已有 0 人评论

Copyright © 2019  萬仟网 保留所有权利. 粤ICP备17035492号-1
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com