浅谈小程序中的请求封装

浅谈小程序中的请求封装

近两个月学习了小程序的开发,并且撸了一个不大不小的demo,算是正式入门了小程序,在此想分享下小程序的开发经验。

前言

在小程序的开发中,或者说在整个前端开发中,请求都是绕不过去的一道坎。在Vue开发中,我们可以采用 axios 这个成熟的插件来进行HTTP请求。但是,遗憾的是,到目前为止,小程序没有一个比较好用的插件来进行HTTP请求。此时,我们需要对小程序的HTTP请求进行封装,以方便我们后续开发。

浅析wx.request

众所周知,在小程序中,我们通过 wx.request 方法来进行HTTP请求(或者说是HTTPS请求)。

通过 官方文档 我们可以知道, wx.request 方法接收一个对象,对象可以有9个属性:urldataheadermethoddataTyperesponseTypesuccessfailcomplete。除了url是必填的以外,其余都是可选项。在这些属性里面,最常用的是 methoddataheadersuccess以及fail这几个属性。毕竟我们总要设置请求方法、请求数据、请求头以及请求成功或失败的处理方法是不是?

所以接下来我们的目标我们已经明确,就是对这些常用属性进行封装。

封装HTTP类

对于HTTP请求的封装,有很多种方法,比如:axios 采用的是通过IIFE作为工厂函数处理并返回一个Axios的实例。在这里,我推荐使用类,因为类的封装形式,正是axios 的封装形式的加强版。

为了一致性,我也采用request作为请求的方法名,并且接受相同的对象作为参数。此时,我们已经可以实现出以下代码:

class HTTP {
    request (params) {
        wx.request({
            url: params.url,
            method: params.method,
            data: params.data,
            header: params.header,
            success: (res) => {
                params.success(res)
            },
            fail: (err) => {
                params.fail(err)
            }
        })
    }
}

接下来,我们需要对各个属性进行处理。

缺省属性处理

由于除了url,其余的的属性皆为可选可选项,所以需要对可选属性进行缺省属性的处理。

在小程序官方文档中,当不传入method属性时,默认采用GET方法,所以我们需要将method的默认值设为GET,设置method的默认值的方式很简单:

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

但是,这种方式不够优雅,我们可以采用位运算符的方式进行默认复制:

...
method: params.method || 'GET'
...

其余属性也采用类似方式进行缺省值处理,除了successfail属性,这个我们后面说。

从配置文件中导入HTTP参数

在正常情况下,REST风格的接口协议给的接口路径都是诸如/pathA/a,在此之前还有一个类似于www.baidu.com/root类似的base url,两者结合才是真正的请求路径。在Vue中,我们可以通过webpack中的proxyTable来解决这个问题,但是,小程序中没有webpack中的proxyTable,所以需要每次请求的时候,都输入完整请求路径。

在HTTP类中的request方法,我们可以实现路径的拼接。

...
url: 'www.baidu.com/root' + params.url,
...

但是,这里有个问题,base url是写死的,也就是说,我们每做一个项目,都需要重新设置一次base url的值,这显然是有问题的。

为了处理该问题,我新建了一个config.js文件,作为该项目的配置文件,用来存储所有项目相关的配置,比如base url以及HTTP Header。

const config = {
  api_base_url: 'www.baidu.com/root',
  // 更多的配置项
}

export {config}

拥有配置文件最大的好处就是,每次修改项目,只需要修改配置文件中的配置项的值即可,重复保证了组件的封闭性,减少了对项目的耦合。

封装success

最后,我们需要封装success以及fail

显而易见,我们只有在HTTP状态码为2**或者304才调用success,所以我们需要对响应结果的状态码进行判断,根据判断结果决定是否执行params.success

...
success: (res) => {
    let code = res.statusCode.toString()
    // 状态码判断
    if (code.startsWith('2') || code === '304') {
        params.success && params.success(res.data)
    } else {
        // 失败
    }
}

tips:一般情况下,我们还可以对显示错误的方法进行一次封装,调用wx.showToast显示服务器返回的错误信息。

全部代码

经过这么多步骤,封装结束后的代码是:

import {config} from '../config.js'

class HTTP {
  request (params) {
    wx.request({
      url: config.api_base_url + params.url,
      method: params.method || 'GET',
      data: params.data || {},
      header: params.header ? Object.asign(config.header, params.header):config.header
      success: (res) => {
        let code = res.statusCode.toString()
        if (code.startsWith('2') || code === '304') {
          params.success && params.success(res.data)
        } else {
          params.fail && params.fail(res.data)
          let error_code = res.data.error_code
          this._show_error(error_code)
        }
      },
      fail: (err) => {
        params.fail && params.fail(res.data)
        this._show_error(1)
      }
    })
  }
    
  // 私有方法,显示请求错误信息
  _show_error(error_code) {
    if (!error_code) {
      error_code = 1
    }
    const tip = config.tips[error_code]
    wx.showToast({
      title: tip ? tip : tips[1],
      icon: 'none',
      duration: 2000
    })
  }
}

其实,HTTP类还可以进一步优化,比如,使用解构以及默认赋值,使用promise等等,篇幅有限,我就不一一细说了,详情可以查看我github上的代码。

代码路径:https://github.com/KarthusLorin/mini-program/blob/master/util/http.js

如果觉得不错,github点个star再走呗?

posted @ 2018-10-30 23:23  格子熊  阅读(8107)  评论(4编辑  收藏  举报