在微信小程序中,封装一个Promise的http请求

文章介绍了如何在JavaScript中封装HTTP请求,利用函数对象的属性和方法扩展功能,包括.get,.post等方法。同时,文章详细阐述了如何创建一个基于axios和微信小程序的封装请求组件,涉及Promise的使用以及请求和响应拦截器的实现,以优化和标准化HTTP请求过程。
摘要由CSDN通过智能技术生成

一些基础的http对象请求配置(封装一个http在后面)

 在JavaScript中,函数也是对象,可以像其他对象一样拥有属性和方法。因此,我们可以给函数添加额外的属性和方法,以扩展函数的功能。

/**
 * 当你调用http.get(url, data, headers)时,实际上是调用了http函数,并传入了一个配置对象
 * @param {*} url 
 * @param {*} headers 
 * @param {*} data 
 * @returns 
 */
http.get = function (url, headers, data) {
  return http({
    method: 'GET',
    url,
    data,
    headers
  })
}

http.post = function (url, headers, data) {
  return http({
    method: 'POST',
    url,
    data,
    headers
  })
}

http.put = function (url, headers, data) {
  return http({
    method: 'PUT',
    url,
    data,
    headers
  })
}

http.delete = function (url, headers, data) {
  return http({
    method: 'DELETE',
    url,
    data,
    headers
  })
}

封装一个http函数

其中的 config 形参所接受的实参就是上述 .get 等方法传入的值

/**
 * 创建一个基于 axios 和 微信小程序的封装请求组件
 * @param {*} config  形参,根据传递的参数 如:{ url, methods, headers, data }
 * @returns wx.request 不支持 Promise ,需要封装一个,然后返回一个 Promise
 */
function http(config) {

  /**
   * new 一个 Promise 实例
   * resolve 和 reject 为返回的成功和失败的函数
   */
  return new Promise((resolve, reject) => {

    // 判断封装的 http 对象中是否存在基地址
    if (http.baseURL) {
      /**
       * 根据获得的基地址和传递的地址来判断 2 者之间是否多出一个 '/'
       */
      if (config.url.startsWith('/')) {
        // startsWith (第一个字符是否是 '/'), endsWith (最后一个字符是否为 '/')
        if (http.baseURL.endsWith('/')) {
          // split(0, -1) (将字符串切割删除)
          config.url = http.baseURL.split(0, -1) + config.url
        } else {
          config.url = http.baseURL + config.url
        }
      } else {
        if (http.baseURL.endsWith('/')) {
          config.url = http.baseURL + config.url
        } else {
          config.url = http.baseURL + '/' + config.url
        }
      }
    }

    // 调用 http 对象中的 响应拦截器 将传入的值 返回一个先的 config 
    config = http.interceptors.request._cb(config)

    if (!config.method) {
      config.method = 'GET'
    }

    // 如果请求头存在
    if (config.headers) {
      // 将其中的值传给 wx.request 中指定的值
      config.header = config.headers
      // 在微信中请求头的键为 header ,而 axios 中的键为 headers
      // 将值传出后删除
      delete config.headers
    }


    wx.request({
      // 将 config 展开传入
      ...config,
      // 调用成功进入的函数
      success(res) {
        res = http.interceptors.response._cb(res)
        // 调用成功,res如果是 Promise ,在其内部会自动区分,
、等待其状态完成再执行,如果正确就返回其值,错误就进入错误的函数
        resolve(res)
      },
      // 调用失败进入的函数
      fail(err) {
        err = http.interceptors.response._cb(err)
        // 是错误的话,直接抛出错误
        if (err instanceof Promise) {
          resolve(err)
        } else {
          reject(err)
        }
      }
    })

  })
}

 在上述中有体现到 Promise 链式调用的特性,在 new Promise((resolve, reject) => { })  实例对象中,在resolve函数中再次调用一个Promise对象时,在其内部会自动去区分,在其状态发生改变后再去执行,成功时返回的值就是她本身的值,失败时就将其本身当做错误抛出,在reject中,同理


 响应拦截器和请求拦截器

http.interceptors = {
  request: {
    _cb: config => config,
    use(cb) {
      this._cb = cb
    }
  },
  response: {
    _cb: res => res,
    use(cb) {
      this._cb = cb
    }
  }
}

其中_cb是一个函数,它接受一个配置对象 config 或者 res 作为参数,并直接返回该配置对象。这个函数的作用是将传入的配置对象原封不动地返回。

1.在请求中,需要先执行拦截器在去执行请求 
2.在 use(cb)中的 cb 就是上述代码中调用成功和失败的 回调

3._cb也是一个 临时的存储变量,方便使用请求拦截器和响应拦截器。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值