微信小程序HTTP请求从0到1封装


Posted in Javascript onSeptember 09, 2019

前言

作为一个前端开发者,从最开始的js、jQuery一把梭,后来的vue、react、angular等MVVM、MVC框架,我们在开发工程中都离不开HTTP库的使用。

HTTP库

1、jQuery的$.ajax

调用了XMLHttpRequest对象,封装在相关函数在配置项中,一旦传入了必需选项,则直接调用相应的send()方法进行数据的请求

2、Axios

基于Promise的请求库,通过判断XMLHTTPRequest对象存在与否,来支持客户端和node服务端发送请求,封装的很不错的HTTP库,支持promise、拦截请求和响应等

小程序网络请求

wx.request({
 url: 'test.php', //仅为示例,并非真实的接口地址
 data: {
 x: '',
 y: ''
 },
 header: {
 'content-type': 'application/json' // 默认值
 },
 success (res) {
 console.log(res.data)
 }
})

小程序本身的请求已经封装的很不错了,使用起来和$.ajax相似,支持许多配置项的设置,但是缺少公共配置、响应和请求拦截等实用功能

第一步--创建请求实例

class Axios {
 constructor() {
  this.instance = null // 类的实例
  this.config = defaultConfig
 }

 create(instanceConfig) {
  const { config } = this
  // 创建实例的时候添加基本配置
  this.config = {
   ...config,
   ...instanceConfig
  }
  return this
 }

 // 单例
 static getInstance() {
  if (!this.instance) {
    this.instance = new Axios()
  }
  return this.instance
 }
}

创建实例

const axios = Axios.getInstance()

promise包装小程序请求

const dispatchRequest = function(config) {
 return new Promise((resolve, reject) => {
  wx.request({
   ...config,
   url: config.base + config.url,
   success: res => {
    resolve(res)
   },
   fail: res => {
    reject(res)
   }
  })
 })
}

给请求实例添加request方法

request(options) {
 const { config } = this
 // 实例请求的时候添加基本配置
 const requsetOptions = {
  ...config,
  ...options
 }
 return dispatchRequest(requsetOptions)
}

第二步--创建请求工具方法

创建实例,通过create设置基本配置项

const instance = (config = {}) => {
 return axios.create({
  base: globalApi,
  ...config
 })
}

创建请求工具方法,执行实例request

export function request(options) {
 const { baseConfig, url, method, data, isLogin } = options
 instance(baseConfig)
  .request({
   url,
   method: method || 'GET',
   data
  })
  .then(res => {
   options.success && options.success(res)
  })
  .catch(err => {
   if (options.error) {
    options.error(err)
   } else {
    errAlert()
   }
  })
 }
}

这样,一个请求的工具方法就完成了,但是这个方法现在只支持基本的请求和基本配置项的配置,还是缺少我们很常用的公共请求和响应的拦截。

第三部--添加请求和响应的拦截器

创建拦截器实例

class InterceptorManager {
 constructor() {
  this.fulfilled = null
  this.rejected = null
 }

 use(fulfilled, rejected) {
  this.fulfilled = fulfilled
  this.rejected = rejected
 }
}

在请求实例的构造方法中添加请求和响应拦截实例

constructor() {
 this.instance = null // 类的实例
 this.config = defaultConfig
 this.interceptors = {
  request: new InterceptorManager(),
  response: new InterceptorManager()
 }
}

在实例的request添加promise执行队列

request(options) {
  const { config, interceptors } = this
  // 实例请求的时候添加基本配置
  const requsetOptions = {
   ...config,
   ...options
  }

  const promiseArr = [] // promise存储队列

  // 请求拦截器
  promiseArr.push({
   fulfilled: interceptors.request.fulfilled,
   rejected: interceptors.request.rejected
  })

  // 请求
  promiseArr.push({
   fulfilled: dispatchRequest,
   rejected: null
  })

  // 回调拦截器
  promiseArr.push({
   fulfilled: interceptors.response.fulfilled,
   rejected: interceptors.response.rejected
  })

  let p = Promise.resolve(requsetOptions)
  promiseArr.forEach(ele => {
   p = p.then(ele['fulfilled'], ele['rejected'])
  })

  return p
 }

在请求工具方法中通过设置请求和响应的拦截方法

axios.interceptors.request.use(
 request => {
  return request
 },
 err => {
  console.error(err)
 }
)
axios.interceptors.response.use(
 response => {
  return response
 },
 err => {
  console.error(err)
 }
)

在请求拦截方法里面可以添加数据转换,在请求头部添加sign、token等,在响应拦截方法里面去做公共的数据处理等

最后

从零搭建一个简单的请求库很简单,但是想考虑的方方面面,设计好整个流程会比较麻烦,需要不断的改进和重构,本文的搭架过程参考了Axios的部分源码。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript 面试题随笔
Mar 31 Javascript
通过Javascript创建一个选择文件的对话框代码
Jun 16 Javascript
javascript写的一个模拟阅读小说的程序
Apr 04 Javascript
Javascript模块化编程详解
Dec 01 Javascript
javascript制作照片墙及制作过程中出现的问题
Apr 04 Javascript
JS模态窗口返回值兼容问题的完美解决方法
May 28 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
Mar 08 Javascript
Bootstrap Table使用整理(一)
Jun 09 Javascript
vue.js根据代码运行环境选择baseurl的方法
Feb 28 Javascript
解决循环中setTimeout执行顺序的问题
Jun 20 Javascript
Angular服务Request异步请求的实例讲解
Aug 13 Javascript
Vue 中使用 typescript的方法详解
Feb 17 Javascript
JS回调函数 callback的理解与使用案例分析
Sep 09 #Javascript
世界上最短的数字判断js代码
Sep 09 #Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
Sep 09 #Javascript
javascript删除数组元素的七个方法示例
Sep 09 #Javascript
微信小程序 select 下拉框组件功能
Sep 09 #Javascript
移动端手指操控左右滑动的菜单
Sep 08 #Javascript
swiper Scrollbar滚动条组件详解
Sep 08 #Javascript
You might like
超人钢铁侠联手合作?美漫作家呼吁DC漫威合作联动以抵抗疫情
2020/04/09 欧美动漫
Laravel中获取路由参数Route Parameters的五种方法示例
2017/09/29 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
简单JS代码压缩器
2006/10/12 Javascript
jquery 应用代码 方便的排序功能
2010/02/06 Javascript
自己用jQuery写了一个图片的马赛克消失效果
2014/05/04 Javascript
JS判断客服QQ号在线还是离线状态的方法
2015/01/13 Javascript
jQuery判断对象是否存在的方法
2015/02/05 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
2015/03/09 Javascript
JS基于HTML5的canvas标签实现炫目的色相球动画效果实例
2016/08/24 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
2017/03/01 Javascript
关于angular js_$watch监控属性和对象详解
2017/04/24 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
基于JavaScript实现抽奖系统
2018/01/16 Javascript
vue弹窗组件使用方法
2018/04/28 Javascript
Vue组件Draggable实现拖拽功能
2018/12/01 Javascript
基于node.js实现爬虫的讲解
2019/02/18 Javascript
JS实现水平遍历和嵌套递归操作示例
2019/08/15 Javascript
在vue中动态添加class类进行显示隐藏实例
2019/11/09 Javascript
微信小程序登陆注册功能的实现代码
2019/12/10 Javascript
Vue中通过vue-router实现命名视图的问题
2020/04/23 Javascript
[01:02]DOTA2上海特锦赛SHOWOPEN
2016/03/25 DOTA
[51:39]DOTA2-DPC中国联赛 正赛 Magma vs LBZS BO3 第二场 2月7日
2021/03/11 DOTA
python实现应用程序在右键菜单中添加打开方式功能
2017/01/09 Python
Tornado协程在python2.7如何返回值(实现方法)
2017/06/22 Python
使用python存储网页上的图片实例
2018/05/22 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
使用Django搭建一个基金模拟交易系统教程
2019/11/18 Python
python使用numpy中的size()函数实例用法详解
2021/01/29 Python
CSS3 中的@keyframes介绍
2014/09/02 HTML / CSS
青年教师培训方案
2014/02/06 职场文书
应聘编辑自荐信范文
2014/03/12 职场文书
校园公益广告语
2014/03/13 职场文书
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis
MySQL 数据库范式化设计理论
2022/04/22 MySQL