找回密码
 立即注册

QQ登录

只需一步,快速开始

[工具插件] 微信小程序网络请求库插件,使用 Promise封装

[复制链接]
查看: 401|回复: 199
最佳答案
0 

2

主题

6

帖子

120

积分

新人求带

积分
120
 楼主| 发表于 2018-5-10 15:10:31 | 显示全部楼层 |阅读模式
本帖最后由 唯我独享 于 2018-5-10 15:13 编辑

微信小程序网络请求库插件,使用 Promise封装

demo.png

功能

  • 减少你70%的代码量,不再一遍遍重复微信的样板代码
  • 调用灵活,错误处理简单而方便
  • 支持并发/并行执行多个请求
  • 自动打印请求日志
  • 支持对请求的发起和响应进一步定制,实现固定参数、自动提取返回值指定数据、自动处理响应错误如token过期自动跳转的功能。


与微信原生请求库对比

微信现有请求方法
  1. let that = this;
  2. wx.request({
  3.     url: SERVER_ROOT + '/user/authorization',
  4.     method: "POST",
  5.     header: {
  6.         'content-type': 'application/x-www-form-urlencoded'
  7.     },
  8.     data: {
  9.         code: res.code
  10.     },
  11.     success(data){
  12.         console.log(data);
  13.         if(data.status && data.status.succeed==1) {
  14.             that.setData({
  15.                 userInfo:data.data.userInfo
  16.             });
  17.         }else {
  18.             wx.showToast({
  19.                 title: "获取数据失败"
  20.             });
  21.         }
  22.     },
  23.     fail(){
  24.         wx.showToast({
  25.             title: "连接服务器失败"
  26.         });
  27.     }
  28. })
复制代码

使用此库后
  1. authorization(res.code).then(data=>{
  2.      this.setData({
  3.         userInfo:data.userInfo
  4.     });
  5. }).catch(e=>{
  6.      wx.showToast({
  7.         title: "连接服务器失败"
  8.     });
  9. })
复制代码

authorization是经过封装的请求方法,一次封装可多处调用。可以看到,原本27行代码量,减少到了8行。下面我们来看如何使用,并定制自己的请求方法。

请求示例

单个请求

  1. getPhoto(1).then(data => this.setData({photo1: data}));
复制代码

带加载框和错误提示
  1. wx.showLoading({title: '加载中'});
  2. getPhoto(2).then(data => {
  3.     this.setData({photo1: data});
  4.     wx.hideLoading();
  5.     // throw '我出错了!'   //todo 你可以尝试抛出一个异常
  6. }).catch(e => {
  7.     wx.showToast({title: '请求失败'});
  8. })
复制代码

多个请求(顺序请求)
  1. getPhoto(3).then(data => {
  2.     this.setData({photo1: data});
  3.     return getPhoto(4); //下一个请求
  4. }).then(data =>{
  5.     this.setData({photo2: data})
  6. });
复制代码

多个请求(同时请求)
  1. Promise.all([getPhoto(5), getPhoto(6)]).then(listData => {
  2.     this.setData({
  3.         photo1: listData[0],
  4.         photo2: listData[1],
  5.     });
  6. });
复制代码

目录说明

  • example 微信小程序的演示项目,
  • util 封装的请求库。


使用方法

跟着本教程一同练习,你马上就能上手。
  • 复制util目录下的network.js和service.js文件到你的项目目录,network.js 存放原始的请求方法,service存放接口。
  • 按需引入service.js中相应请求方法并调用。

定义接口

在service.js中定义请求方法
  1. import {get, post} from './network';

  2. const API_ROOT = 'https://jsonplaceholder.typicode.com'; //服务器根路径

  3. //请求图片
  4. export function getPhoto(id){
  5.     const url = API_ROOT + '/photos/' + id;
  6.     return get(url);
  7. }
复制代码

引入和调用
  1. import {getPhoto} from '../../util/service';

  2. onLoad(){
  3. getPhoto(1).then(data =>{
  4.     this.setData({photo1: data}));
  5. }
  6. },
复制代码

使用then方法就可以获取到返回值了,如果需要处理错误,再在后面接catch方法,详见上面第二个请求示例。

教程到这里就结束了,是不是很简单?

进一步封装示例

也许你还想要一些高级特性,比如说处理诸如固定参数、自动提取返回值指定数据、自动处理响应错误、登录凭证过期提示用户并自动跳转等功能。那你就会用到下面的进阶教程了。

例1:固定参数

某些接口需要固定传参,比如说平台标识、用户凭证、特定的header等等。如果每次调用都要手动传入,不仅麻烦,而且也不利于修改。

以接口要传入指定header参数为例,有了network.js这层封装,现在我们可以这样做:

找到network.js下的这段代码:
  1. /**
  2. * 接口请求基类方法
  3. * @param method 请求方法 必填
  4. * @param url 请求路径 必填
  5. * @param data 请求参数
  6. * @param header 请求头
  7. * @returns {Promise}
  8. */
  9. export function request(method, url, data, header = {'Content-Type': 'application/json'}) {
  10.     console.info(method, url);
  11.     return new Promise((resolve, reject) => {
  12.         const response = {};
  13.         wx.request({
  14.             url, method, data, header,
  15.             success: (res) => response.success = res.data,
  16.             fail: (error) => response.fail = error,
  17.             complete: () => { ... },
  18.         });
  19.     });
  20. }
复制代码

这里我们把微信的wx.request API封装成了自定义request方法,返回了一个Promise对象。我们的get、post、put、delete最终调用的都是这个方法。
我们要定义该方法的第四个参数header(请求头),它有一个默认值header = {'Content-Type': 'application/json'},当我们没有传入header时,它会自动使用默认值,我们可以直接改变这个值:
  1. export function request(method, url, data, header = 'Content-Type': 'application/json'}) {
  2.      ...
  3. }

  4. =>

  5. export function request(method, url, data, header ={'Content-Type': 'application/x-www-form-urlencoded'}) {
  6.      ...
  7. }
复制代码

这样,所有接口将会使用新的默认header参数进行请求了。

例2:自动解析数据

服务器返回的数据往往有某种固定格式,需要我们做一些变换才能使用。拿一个典型的返回值例子来说:
  1. {
  2.     "code":1,
  3.     "data":{
  4.         "name":"凯"
  5.     },
  6.     "message":""
  7. }
复制代码

我们拿到数据首先要判断code值是否为1,才能正常取出需要的data里面的字段,不为1则要做错误处理。假如每次都对返回值做判断,我们的代码会变得更加凌乱和难于维护。 还是在network.js方法里:
  1. export function request(method, url, data, header = {'Content-Type': 'application/json'}) {
  2.     console.info(method, url);
  3.     return new Promise((resolve, reject) => {
  4.         const response = {};
  5.         wx.request({
  6.             url, method, data, header,
  7.             success: (res) => {
  8.                 if (res.data.code === 1) { //判断code值
  9.                     response.success = res.data.data; // 你将在then方法中看到的数据
  10.                 } else {
  11.                     response.fail = res.data; // 你将在catch方法中接收到该错误
  12.                 }
  13.             },
  14.             fail: (error) => response.fail = error,
  15.             complete: () => { ... },
  16.         });
  17.     });
  18. }
复制代码

通过改造,我们再次调用service.js中定义的方法将会直接得到正确的数据。

例3:通用错误处理

服务器返回的错误往往有规律可循,以下面这段返回值为例:
  1. {
  2.     "code":-2,
  3.     "data": null,
  4.     "message":"登录已过期"
  5. }
复制代码

接前面的例子,当code值不为1时,message字段返回异常信息,不同的code值我们要做不同的处理,处理方法跟例2相近。

这里假设code为-2时,代表登录过期,需要跳转到登录页
  1. export function request(method, url, data, header = {'Content-Type': 'application/json'}) {
  2.     console.info(method, url);
  3.     return new Promise((resolve, reject) => {
  4.         const response = {};
  5.         wx.request({
  6.             url, method, data, header,
  7.             success: (res) => {
  8.                 if (res.data.code === 1) {
  9.                     response.success = res.data.data; // 你将在then方法中看到的数据
  10.                 } else if (res.data.code === -2) {
  11.                     wx.navigateTo({url:'/pages/login/login'}); // 跳去登录页
  12.                 } else {
  13.                     response.fail = res.data; // 你将在catch方法中接收到该错误
  14.                 }
  15.             },
  16.             fail: (error) => response.fail = error,
  17.             complete: () => { ... },
  18.         });
  19.     });
  20. }
复制代码

这样,当任何一个返回的code值为-2时,小程序都会跳到登录页了。

源码: wx_network-master.zip (21.35 KB, 下载次数: 3)
回复

使用道具 举报

最佳答案
0 

0

主题

23

帖子

210

积分

新人求带

积分
210
发表于 2018-5-10 15:43:30 | 显示全部楼层
学习了,本以为这只是个单纯的源码论坛,没想到还是学习的地方
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

331

帖子

1651

积分

专家路上

积分
1651
发表于 2018-5-10 15:48:57 | 显示全部楼层
学习了学习了学习了
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

1443

帖子

2257

积分

专家路上

积分
2257
发表于 2018-5-10 16:20:47 | 显示全部楼层
学习一下
回复

使用道具 举报

最佳答案
0 

0

主题

113

帖子

633

积分

略知一二

积分
633
发表于 2018-5-10 16:26:05 | 显示全部楼层
感谢楼主分享
回复 支持 反对

使用道具 举报

最佳答案
0 

3

主题

1052

帖子

3282

积分

专家路上

积分
3282
发表于 2018-5-10 18:29:37 | 显示全部楼层
qwerqwer仍你用鬼脸的qwe
回复 支持 反对

使用道具 举报

最佳答案
0 

3

主题

1052

帖子

3282

积分

专家路上

积分
3282
发表于 2018-5-10 18:29:45 | 显示全部楼层
qwerqwer仍你用鬼脸的qwe
回复 支持 反对

使用道具 举报

最佳答案
0 

3

主题

1052

帖子

3282

积分

专家路上

积分
3282
发表于 2018-5-10 18:29:55 | 显示全部楼层
qwerqwer仍你用鬼脸的qwe
回复 支持 反对

使用道具 举报

最佳答案
0 

3

主题

1052

帖子

3282

积分

专家路上

积分
3282
发表于 2018-5-10 18:29:58 | 显示全部楼层
qwerqwer仍你用鬼脸的qwe
回复 支持 反对

使用道具 举报

最佳答案
0 

3

主题

1052

帖子

3282

积分

专家路上

积分
3282
发表于 2018-5-10 18:30:07 | 显示全部楼层
qwerqwer仍你用鬼脸的qwe
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



www.henkuai.com—微信开发者的分享交流平台,专注微信开发生态。

天津市滨海新区
中新生态城中成大道生态建设公寓9号楼3层301

微信公众号

广告推广
zhongcong@henkuai.com

市场合作
zhongcong@henkuai.com