已经好久没有搞小程序的我,刚好公司来了个小程序的项目。小程序中数据请求用到的是比较多的,所以我们来封装一下
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)
},
})