微信小程序开发技巧:微信请求Promise
2.1 使用成品库
安装promise库wx-promise-pro。记得带上-s
或--生产
,否则构建不会成功。
npm i -S wx-promise-pro
然后在app.js
:
import { promisifyAll } from 'wx-promise-pro' promisifyAll() // promisify all wx api App({ ... })
然后就可以正常使用了:
wx.pro.showLoading({ title: '加载中', mask: true }) .then(() => console.log('in promise ~'))
2.2 自己实现
其实我们可以自己实现这样一个库。原理很简单,以原生 API 的 wx.request 为例:
// 原生 API 使用方式 wx.request({ url: '', // 请求的 url data: {}, // 参数 method: '', // post、get success: res => { // 请求成功回调函数,res为回调参数 }, fail: res => { // 请求失败回调函数,res为回调参数 } })
如果我们让它成为一个 Promise,那么调用方法应该是:
// Promise 化后的期望使用方式 wx.pro.request({ url: '', // 请求的 url data: {}, // 参数 method: '' // post、get }) .then(res => { // 请求成功回调函数,res为回调参数 }) .catch(res => { // 请求失败回调函数,res为回调参数 })
And then
该函数给出了一个 Promise -return object ,所以这个函数可以调用链继续下去,所以我们首先需要 new
来获取一个 Promise 对象:
function request(opt) { return new Promise((resolve, reject) => { wx.request({ ...opt, success: res => { resolve(res)}, fail: res => {reject(res)} }) }) }
我们可以进一步改进这段代码,因为 另外,由于其他小程序的原生 API 格式是一样的,所以我们可以使用 curry 方法来处理其他需要 Promise 的 API: 那么 curry 的结果就是 -method as new 的 Promise基于 的 API 挂载在 然后为了方便我们使用其他方法,我们可以通过基于对象的 其实在不知不觉中,我们实现了 有了上面的工具我们就可以在项目中使用了。为了不将它们分散到整个项目中 然后将所有API封装在单独的文件中,集中管理: 你想在哪里使用API,你可以这样想象: 使用方式非常方便,这里用到了upData,这是我下面介绍的一个我强烈推荐的小程序工具~ Success fail此处输入参数仅使用
resolve
、reject
方法执行,因此它们会立即ve。reject 方法就够了。 function promisify(api) {
return (opt = {}) => {
return new Promise((resolve, reject) => {
api({
...opt,
fail: reject,
success: resolve
})
})
}
}
wx.pro
对象上: // 将指定 API 进行 Promise 化
wx.pro.request = promisify(wx.request)
// 使用
wx.pro.request({...})
.then(...)
wx 方法来释放 Promise,比如
请求
、扫描代码
、显示Toast❀、er等。被一个接一个地安装。
wx.pro
对象,可以直接使用wx.pro.xx
。由于此方法返回一个 Promise 对象,因此可以像任何其他 Promise 对象一样使用它。 wx-promise-pro
的源代码。这个库的核心代码就是上面几行?2.3 项目中使用
wx.request
或wx.pro.request
这里我们可以简单地封装它们并创建两个新的。文件如下: // utils/api/fetch.js 封装请求方法、请求拦截器
const app = getApp()
const BaseUrl = 'http://172.0.0.1:7300/mock'
const TokenWhiteList = [
'/app/user/get-by-code' // 不需要鉴权的api手动添加到这里
]
/**
* 设置请求拦截器
* @param params 请求参数
*/
const fetch = (params = {}) => {
// 拦截器逻辑
if (!TokenWhiteList.includes(params.url)) {
params.header = {
'content-type': 'application/json', // 默认值
'token': app.globalData.token || ''
}
}
if (params.url.startsWith('/')) { // 拼接完整URL
params.url = BaseUrl + params.url
}
// 返回promise
return wx.pro.request({ ...params })
.then(({ data: { code, message, data } }) => {
// ... 各种异常情况的逻辑处理
// 与后端约定 code 20000 时正常返回
if (code === 20000) return Promise.resolve(data)
return Promise.reject(message)
})
}
export { fetch }
// utils/api/apis.js 封装所有请求 API
import { fetch } from './fetch'
/* 根据微信code获取用户信息 */
const appUserGetByCode = ({ code } = {}) => fetch({
url: '/app/user/get-by-code',
data: { code }
})
/* 扫码登录 */
const appUserQrLogin = ({ qrCode } = {}) => fetch({
method: 'POST',
url: '/app/user/qr-login',
data: { qrCode }
})
/* 个人信息 */
const appUserInfo = () => fetch({
url: '/app/user/info'
})
/* 系统参数获取,数据字典 */
const appSysParamListByParam = () => fetch({
url: '/app/sys-param/list-by-param'
})
/* 数据字典所有 */
const appSysParamListAll = () => fetch({
url: '/app/sys-param/list-all'
})
export {
appSysParamListAll, // 数据字典所有
appSysParamListByParam, // 系统参数获取,数据字典
appUserGetByCode, // 根据微信code获取用户信息
appUserQrLogin, // 扫码登录
appUserInfo // 个人信息
}
import * as Api from '../../utils/api/apis.js' // 相对路径
// 使用方式
Api.appSysParamListAll()
.then(({ dataList }) => this.upData({ sysParamList: dataList }))
.then(() => {
const keyList = this.data.sysParamList.map(T => T.key)
this.upData({
keyList,
formData: { keys: keyList }
})
})
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。