微信小程序所有API promise化,支持await、支持请求列队.核心代码Fock自wepy框架,我将之去依赖单独剥离
- 微信官方小程序自基础库 v1.4.0 (2017.07.10) 版本起,request 超过并发限制做队列处理;
- 微信官方小程序自基础库 v2.10.2 (2020-02-20) 版本起,所有异步api均支持返回promise;
- 基于上面两点,此库已经失去了存在价值
如果只是想发请求时使用拦截器的,可以转向使用 axios-miniprogram-adapter库 ,在小程序中使用 axios
如果你为你的小程序代码配置了工作流环境(比如webpack
),可以通过npm下载安装代码
$ npm install minapp-api-promise --save
引入代码
import WXP from 'minapp-api-promise'
如果你没有使用任何脚手架,用官方提供的微信开发者工具开发,请拷贝项目dist
目录下的wxp.js
文件到你的项目目录
引入代码
import WXP from '项目相对路径/wxp'
或者
var WXP = require('项目相对路径/wxp').default
具体你可以参照 demo1,并且注意没有脚手架这种情况下你不能使用async/await
,只能使用then/catch
小程序原生用法:
onLoad () {
wx.request({
url: 'http://baidu.com',
success: resp => {
console.log('success信息:', resp)
},
fail: errorMesg => {
console.log('fail信息:', errorMesg)
},
complete: resp => {
console.log('complete一定会执行:', resp)
}
})
}
使用了本库后的async/await
写法:
async onLoad () {
try {
let resp = await WXP.request({
url: 'http://baidu.com'
})
console.log('success信息:', resp)
} catch (errorMesg) {
console.log('fail信息:', errorMesg)
} finally () {
console.log('complete一定会执行')
}
}
你也可以使用promise
的then/catch
写法:
onLoad () {
WXP.request({
url: 'http://baidu.com'
}).then(resp => {
console.log('success信息:', resp)
}).catch(errorMesg => {
console.log('fail信息:', errorMesg)
})
}
其他所有的微信小程序原生api(具备异步回调函数的api)使用方法同上
可以使用全局拦截器对原生API接口进行拦截
比如某些页面需要登录才能看,我们可以拦截路由,在跳转前判断跳转的页面是否需要登录:
WXP.intercept('navigateTo', {
config (config) {
console.log('路由跳转前需要处理的事情')
if (页面没有权限) {
// 返回false 后,就不会再执行跳转轻轻
return false;
}
return config;
}
})
// 这样调用就会进入拦截
WXP.navigateTo(配置);
比如某些API请求需要在请求头带上token。 参考示例(拦截小程序发起的原生请求):
import WXP from 'minapp-api-promise'
WXP.intercept('request', {
// 发出请求时的回调函数
config (playload) {
// 对所有request请求中的OBJECT参数对象统一附加时间戳属性
playload.timestamp = +new Date();
console.log('request before config: ', playload);
// 必须返回OBJECT参数对象,否则无法发送请求到服务端
return playload;
},
// 请求成功后的回调函数
success (resp) {
// 可以在这里对收到的响应数据对象进行加工处理
console.log('request success: ', resp);
// 必须返回响应数据对象,否则后续无法对响应数据进行处理
return resp
},
//请求失败后的回调函数
fail (resp) {
console.log('request fail: ', resp);
// 必须返回响应数据对象,否则后续无法对响应数据进行处理
return resp;
},
// 请求完成时的回调函数(请求成功或失败都会被执行)
complete (resp) {
console.log('request complete: ', resp);
}
})
requestIntercept.js
/*
* @description: 网络请求拦截器(注意拦截器中的this是指向minapp-api-promise实例本身)
* @Author: bigmeow
* @Date: 2018-03-26 15:59:42
*/
export default{
// 发出请求时的回调函数
config (config) {
// 请求前设置token
const globalData = getApp().globalData
if (globalData.auth && globalData.auth.token) {
config.header = {
Authorization: globalData.auth.token
}
}
return config
},
// 请求成功后的回调函数
async success (resp) {
this.hideLoading()
let errorMesg = ''
// 可以在这里对收到的响应数据对象进行加工处理
switch (resp.statusCode) {
case 200:
console.log('正常请求')
break
case 401:
console.log('未登陆,拦截重定向登陆界面')
await this.redirectTo({
url: 'login'
})
break
case 403:
console.log('未授权接口,拦截')
this.showModal({
title: '警告',
content: (resp.data.error && (resp.data.error.details || resp.data.error.message)) || '无权请联系管理员',
confirmText: '我知道了',
showCancel: false
})
throw new Error(errorMesg)
case 500:
case 502:
errorMesg = (resp.data.error && (resp.data.error.details || resp.data.error.message)) || '服务器出错'
break
case 503:
errorMesg = '哦~服务器宕机了'
break
}
if (errorMesg.length > 0) {
this.showToast({
title: errorMesg,
icon: 'none'
})
throw new Error(errorMesg)
}
return resp
},
fail (resp) {
this.hideLoading()
this.showToast({
title: '网络连接失败',
icon: 'none'
})
}
}
页面.js
引入
import wxp from 'minapp-api-promise'
import requestIntercept from '相对目录/requestIntercept'
// 注册请求拦截器
wxp.intercept('request', requestIntercept)
- 某些古老设备不支持Promise对象,需要自行引入promise-polyfill库进行兼容;
- 使用async/await语法糖,需要webpack配合babel插件将之转换成es5语法