关于对小程序网络请求的封装(详尽版)

引导读者从最基础的小程序网络请求封装到网络请求封装的最优解

在使用原生小程序网络api时,有以下两个缺点:

  1. 多个页面往往代表发送多个网络请求,这样对服务器的压力过大 -> 降压
  2. 基于原因1,防止未来微信官方废弃了wx.request这个api而换了另外一个api时造成的重复操作 ->降低依赖,防止重复

1. wx原生网络请求

技术图片

微信原生请求看似很清晰,但成功与失败的函数都是在 wx.request内部,假设读者对jQuery有所了解,就会发觉跟jquery很像:

技术图片

但这种方法已经濒临灭绝了,接下来使用基于promise对微信原生网络请求进行层层封装


2. 简单封装

// ../../request/one.jsexport default function reqeust(params) { return new Promise((resolve, reject) => { wx.request({ url: params.url, method: params.method || ‘get‘, data: params.data || {}, success: res => { resolve(res) }, fail: err => { reject(err) } }) })}

如果对pomise相当了解,也可以使用进化版:

// ../../request/one.jsexport default function reqeust(params) { return new Promise((resolve, reject) => { wx.request({ url: params.url, method: params.method || ‘get‘, data: params.data || {}, success: resolve, fail: reject }) })}

页面内使用:

//页面内导入 import reqeust from ‘../../request/one.js‘// 页面的onload函数内使用 onLoad: function () { reqeust({ url: ‘https://xxxxxxxxxxxxxxxxxxxxxxxxxxx‘, }) .then(res => { console.log(res) }) .catch(err => console.log(err)) } 

结果也是一样的


3. 进化版封装

回顾下es6的导入导出知识:

// 常量的导出//public.jsconst demo = ‘使用export导出的常量,不可以重命名该常量,需要用大括号‘;export { demo }//常量的导入//getdemo.jsimport { demo } from ‘./public‘console.log(demo ) // ‘使用export导出的常量,不可以重命名该常量,需要用大括号‘//函数的导出与导入//函数的导出//fn.jsexport function fn() { console.log("使用export导出的fn,不可以重命名该函数,需要用大括号")}//函数的导入//getFn.jsimport { fn } from ‘./fn.js‘fn(); // "使用export导出的fn,不可以重命名该函数,需要用大括号"//全部导出与导入//导出//allData.jsexport default function allData() {console.log("使用export default 导出的数据,可以重命名该函数,不需要用大括号")}//getAllData.js//导入 import reName_AllData from ‘./allData.js‘reName_AllData()//"使用export default 导出的数据,可以重命名该函数,不需要用大括号"

假设请求的url有一部分是相同的

  • 将url分为两部分:第一部分作为公共的请求地址publicURL,单独抽离成一个文件,另一部分作为单个页面请求的网络地址PageUrl
  • 在requers.js里将公共的请求地址publicURL添加进url里
  • 页面导入request.js 发起请求
//抽取公共url到单独文件//publicData.jsconst baseURL = ‘https://jiazhuang/zheshi/yige/gonggongurl‘;export { baseURL}//封装的网络请求文件,导入上述文件//network1-0.jsimport { baseURL } from ‘./public‘export function request(params) { return new Promise((resolve, reject) => { wx.request({ url: baseURL + params.url, method: params.method || ‘get‘, data: params.data || {}, success: resolve, fail: reject }); })}//页面使用时仅填入对应的网络地址即可//页面导入封装好的network1-0.jsimport { request } from ‘../../req/newwork1-5‘//onLoad函数内使用 onLoad: function () { request({ url: ‘public/v1/home/swiperdata‘ }).then(res => { console.log(res) }) .catch(err => console.log(err)) }

以上就是第二层封装.

但是这样还是有不太方便的一面:
单个页面需要发送的请求太多,代码的可读性并不太好
那么就有了终极版封装:

4. 进化版封装

这一步时,我们的目的就是为了分层:

基于页面分层,封装单个页面需要发送的请求为一个文件getPage.js由page.js负责向request.js发送真正的网络请求,而页面要做的就是调用page.js里的单个请求方法
以下为图示:
技术图片

解释:

  1. request.js负责将公共api与getPage.js里传入的api进行拼接,整合后向后台发送数据
  2. getPage.js向上负责向request.js发送请求,向下作为发送请求函数等待被调用,函数内部存储非公共api
  3. page作为页面,仅调用getPage.js内部的函数即可

整演示例

//publicData.js 作为api的公共部分 const baseUrl= ‘https://jiazhuang-shiyige-api/api/‘;export { baseUrl}//request.js 作为真正发送网络请求的文件import { publicUrl } from ‘./publicData‘export default function reqeust(params) { return new Promise((resolve, reject) => { wx.request({ url: publicUrl + params.url, method: params.method || ‘get‘, data: params.data || {}, success: resolve, fail: reject }) })}// getIndexData.js : 向上负责调用request.js,向下负责该page页面的发送网络请求的所有函数,函数的内部存储了非公共部分的请求地址import reqeust from ‘./request‘export function getBannerData() { return reqeust({ url: ‘wo/zhen-de/shi/api/banner‘, })}//index页面导入所属的getIndexData.js,在onload函数内调用所属页面的方法import { getBannerData} from ‘../../request/getIndexData‘onload(){ getBannerData().then(res => { console.log(res) //这里就可以对数据进行操作了 }).catch(err => console.log(err))}

在这个例子里,一步步解释了流程,或许有些冗余,但这些更符合了规范化,page页面不关心发送网络请求,只负责调用,getPageData.js只负责将对应的url发送给request.js处理,而request.js负责拼接整合url以及其他,最终发送向网络请求.如果愿意,还可以单个页面再细分,所作的一切都是为了服务于开发.

以上就是将小程序的原生网络请求一步步封装达到最优解.
技术图片

相关文章