• 技术文章 >微信小程序 >小程序开发

    原生小程序如何封装请求,优雅地调用接口?

    青灯夜游青灯夜游2021-12-02 10:26:42转载568
    微信小程序如何封装原生请求?如何调用接口?下面本篇文章给大家介绍一下原生微信小程序封装请求,并优雅调用接口的方法,希望对大家有所帮助!

    本文属于代码片段,对于原生微信小程序请求的封装。有个人书写习惯,仅供参考。

    基于小程序原生request封装Promise风格的请求
    避免多级回调(回调地狱)
    对于网络请求错误统一处理分发

    目录结构

    .
    ├── api
    │   ├── config.js // 相关请求的配置项,请求api等
    │   ├── env.js // 环境配置
    │   ├── request.js  // 封装主函数
    │   ├── statusCode.js // 状态码
    └── ...

    相关代码

    配置文件

    env.js

    // env.js
    module.exports = {
      ENV: 'production',
      // ENV: 'test'
    }

    statusCode.js

    // statusCode.js
    // 配置一些常见的请求状态码
    module.exports = {
      SUCCESS: 200,
      EXPIRE: 403
    }

    config.js

    // config.js
    const { ENV } = require('./env')
    let BASEURL
    
    switch (ENV) {
      case 'production':
        BASEURL = ''
        break
      case 'test':
        BASEURL = ''
        break
      default:
        BASEURL = ''
        break
    }
    module.exports = {
      BASEURL,// 项目接口地址,支持多域名
    }

    主函数

    注意 64~68行是对token过期的处理,在调用登录的时候, 检查app.globalData中是否存在token,存在则不发起登录请求,token过期清空token,那么下一次请求的时候就会 重新发起登录请求从而会重新获取到新的token

    // 引入状态码statusCode
    const statusCode = require('./statusCode')
    // 定义请求路径, BASEURL: 普通请求API; CBASEURL: 中台API,不使用中台可不引入CBASEURL
    const { BASEURL } = require('./config')
    // 定义默认参数
    const defaultOptions = {
      data: {},
      ignoreToken: false,
      form: false,
    }
    /**
     * 发送请求
     * @params
     * method: <String> 请求方式: POST/GET
     * url: <String> 请求路径
     * data: <Object> 请求参数
     * ignoreToken: <Boolean> 是否忽略token验证
     * form: <Boolean> 是否使用formData请求
     */
    function request (options) {
      let _options = Object.assign(defaultOptions, options)
      let { method, url, data, ignoreToken, form } = _options
      const app = getApp()
      // 设置请求头
      let header = {}
      if (form) {
        header = {
          'content-type': 'application/x-www-form-urlencoded'
        }
      } else {
        header = {
          'content-type': 'application/json' //自定义请求头信息
        }
      }
      if (!ignoreToken) {
        // 从全局变量中获取token
        let token = app.globalData.token
        header.Authorization = `Bearer ${token}`
      }
      return new Promise((resolve, reject) => {
        wx.request({
          url: BASEURL + url,
          data,
          header,
          method,
          success: (res) => {
            let { statusCode: code } = res
            if (code === statusCode.SUCCESS) {
              if (res.data.code !== 0) {
                // 统一处理请求错误
                showToast(res.data.errorMsg)
                reject(res.data)
                return
              }
              resolve(res.data)
            } else if (code === statusCode.EXPIRE) {
              app.globalData.token = ''
              showToast(`登录过期, 请重新刷新页面`)
              reject(res.data)
            } else {
              showToast(`请求错误${url}, CODE: ${code}`)
              reject(res.data)
            }
          },
          fail: (err) => {
            console.log('%c err', 'color: red;font-weight: bold', err)
            showToast(err.errMsg)
            reject(err)
          }
        })
      })
    }
    
    // 封装toast函数
    function showToast (title, icon='none', duration=2500, mask=false) {
      wx.showToast({
        title: title || '',
        icon,
        duration,
        mask
      });
    }
    
    function get (options) {
      return request({
        method: 'GET',
        ...options
      })
    }
    
    function post (options) {
      // url, data = {}, ignoreToken, form
      return request({
        method: 'POST',
        ...options
      })
    }
    
    module.exports = {
      request, get, post
    }

    使用方法

    新建文件

    新建api文件(此处以订单接口为例), 新建api/index.js(接口分发统一处理,防止接口写到同一个文件下过于冗长)
    目录结构如下:

    .
    ├── api
    │   ├── config.js // 相关请求的配置项,请求api等
    │   ├── index.js  // 统一处理入口
    │   ├── order.js  // 订单接口
    │   ├── request.js  // 封装主函数
    │   ├── statusCode.js // 状态码
    └── ...

    引入request

    // order.js
    const request = require('./request')
    
    module.exports = {
      // data可以传入 url, data, ignoreToken, form, cToken
      apiName (data) {
        let url = 'apiUrl'
        return request.post({ url, data })
      }
    }

    统一分发接口

    const orderApi = require("./order")
    
    module.exports = {
      orderApi
    }

    页面引用

    const { orderApi } = require('dir/path/api/index')
    ...
    1. `Promise.then()`链式调用
    func () {
      orderApi.apiName(params).then(res => {
        // do Something
      }).catch(err => {
        // do Something
      })
    }
    
    2. `async/await` 调用
    async func () {
      try {
        let res = await orderApi.apiName(params)
        // do Something
      } catch (err) {
        // do Something
      }
    }

    options取值

    参数说明数据类型默认值
    url接口名String''
    data请求体Object{}
    ignoreToken请求是否携带tokenBooleanfalse
    form是否是表单请求Booleanfalse

    【相关学习推荐:小程序开发教程

    以上就是原生小程序如何封装请求,优雅地调用接口?的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    上一篇:浅析小程序中reLaunch跳转报错怎么解决 下一篇:手把手教你怎么部署微信小程序并上线
    千万级数据并发解决方案

    相关文章推荐

    • 深入聊聊小程序中怎么进行图片优化• 聊聊小程序中怎么同步或异步操作本地存储• 浅析小程序中怎么引入高德地图• 浅析小程序中textarea层级过高穿透问题的解决方案• 通过实例了解一下小程序中怎么实现canvas拖动功能
    1/1

    PHP中文网