微信小程序请求封装

381 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第32天,点击查看活动详情 1、为什么封装 官方文档有api,直接用不就可以吗?为什么要封装小程序的请求呢?

封装是为了方便维护和管理 封装后直接传参、调用即可 减少重复的请求代码,提高优雅度 2、开始封装 封装的时候要考虑到一些通用性和临界点,比如:没网络请求怎么办、loading效果、错误提示等等

将重要的一些参数赋默认值,比如:url、method等等

2-1. 根目录下新建@/utils/constant.js常量文件

目的 因为之前一直在使用vue开发,相较于微信小程序的wx.request里面的回调,还是感觉async和await使用起来比较方便,是以想继续使用此方法进行操作。同时,因为每次后端接口请求都要携带上token,为了方便操作,将其进行封装,使之每次请求自动加上token,简便编程

1、为什么封装 官方文档有api,直接用不就可以吗?为什么要封装小程序的请求呢?

封装是为了方便维护和管理 封装后直接传参、调用即可 减少重复的请求代码,提高优雅度 2、开始封装 封装的时候要考虑到一些通用性和临界点,比如:没网络请求怎么办、loading效果、错误提示等等

将重要的一些参数赋默认值,比如:url、method等等

2-1. 根目录下新建@/utils/constant.js常量文件

/* 请求地址 */
export const tempUrl = '联调时候的临时地址'
export const httpUrl = 'https://xxxxxxx'

/* http错误码 */
export const errCodeArr = [500, 502, 503, 504, 403, 404, 400, 401]
export const errMsgMap = {
  400: '请求错误',
  401: '登录状态失效,请重新登录',
  403: '拒绝访问',
  404: '请求地址不存在',
  500: '服务器繁忙',
  502: '网关错误',
  503: '服务不可用,服务器暂时过载或维护',
  504: '网关超时'
}

2-2. 根目录下新建@/service/request.js网络请求

import {httpUrl, errCodeArr, errMsgMap} from '../utils/constant'
//这几个方法主要是从本次取出后台返回的token、判断变量是否是Object、返回网络情况,代码很简单就不展示了
import {getToken} from '../utils/storage'
import {isObject} from '../utils/type'
import {getNetworkType} from '../utils/util'
 
export default function request(options, finishCb) {
  return new Promise(async (resolve, reject) => {
    const networkRes = await getNetworkType()
    if (networkRes.networkType === 'none') {
      wx.showToast({
        title: '无网络!',
        icon: 'none'
      })
      reject(networkRes)
      return
    }
    
	const token = getToken()
    if (!token) {
      wx.showToast({
        title: '暂未登录',
        icon: 'none'
      })
      return
    }
    const {
      url,
      method = 'GET',         
      title = '加载中...',       // loading文字
      failText = '请求数据失败', // 请求失败描述
      errTip = 'toast',         // 错误提示,是Toast还是Modal
      data = {}, 
      header = {},
      mask = false,             // 是否开启mask
      loading = true,           // 是否loading
      timeout = 8000,           // 超时时间
      hideLoadingTime = 500     // 多少毫秒隐藏loading
    } = options
    const tHeader = {'cookie': token, ...header}

    loading && wx.showLoading({title, mask}) 
    wx.request({
      url,
      method,
      timeout,
      data,
      header: tHeader,
      success(res) {
        if (!isObject(res.data)) {
          wx.showToast({
            title: '服务端异常',
            icon: 'error'
          })
          return
        }
        // 针对错误码进行处理
        const {statusCode, data = {}} = res
        if (errCodeArr.includes(statusCode)) {
          wx.showToast({
            title: data.msg || errMsgMap[statusCode],
            icon: 'error'
          })
          
          return Promise.reject(res)
        }
        
        if (!data.flag) {
          errTip === 'toast' && wx.showToast({title: data.message})
          errTip === 'modal' && wx.showModal({
            showCancel: false,
            content: data.message 
          })
        }
        
        resolve(data)
      },
      fail(err) {
        wx.showToast({
          title: failText,
          icon: 'error'
        })
        reject(err)
      },
      complete() {
        const timer = setTimeout(() =>{
          wx.hideLoading()
          clearTimeout(timer)
        }, hideLoadingTime)
        finishCb && finishCb()
      }
    })
  })
}

3、使用

建议根据项目的模块进行分开封装请求,比如所有商品相关的请求放在@/service/goods.js中,不过看个人

在你的某个页面的js中

import request from '../serrvice/request'

Page({
   async onLoad() {
     const res = await request({
        url: 'xxxxxxx',
        method: 'post'
     })
     console.log(res)
  },
})