默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的,例如,网络请求的 API 需要按照如下的方式调用
wx.request({
url: '',
method: '',
data: {},
success: (res) => {
console.log(res);
},
fail: (res) => {
console.log(res);
},
complete: (res) => {
console.log(res);
}
})
这种代码的缺点是显而易见的, 容易造成回调地狱的问题,代码的可读性、维护性差。而我们就想将这种类型的代码使用 `API Promise` 化进行改造,从而提高代码的可读性、维护性,避免回调地狱的问题。
1.手动实现wx.request的Promise化
//Promise化
requestPromise(url, method) {
return new Promise((resolve, reject) => {
wx.request({
url,
method,
success: (res) => {
resolve(res)
},
fail: (res) => {
reject(res)
}
})
})
},
//调用----方法一
getRequest() {
this.requestPromise('https://www.escook.cn/categories', 'GET').then(res=>console.log(res),err=>console.log(err))
}
//调用----方法二
getRequest() {
this.requestPromise('https://www.escook.cn/categories', 'GET').then(res=>console.log(res)).catch(err=>console.log(err))
}
//调用----方法三
async getRequest() {
try{
const res = await this.requestPromise('https://www.escook.cn/categories', 'GET')
console.log(res);
}catch(err){
console.log(err);
}
},
2.使用 @escook/request-miniprogram
第三方包实现wx.request的Promise化
npm install @escook/request-miniprogram
在项目的入口文件中,通过如下的方式进行配置:
import { $http } from '@escook/request-miniprogram'
// 配置请求根路径
$http.baseUrl = '项目请求根路径...'
// 请求开始之前
$http.beforeRequest = function (options) {
uni.showLoading({
title: '数据加载中...',
})
}
// 请求完成之后
$http.afterRequest = function () {
uni.hideLoading()
}
// 在 uni-app 项目中,将 $http 挂载到uni全局对象上,方便全局调用
uni.$http = $http
// 在小程序中,将 $http 挂载到 wx 顶级对象之上,方便全局调用
wx.$http = $http
//使用
async getSwiperList() {
// 3.1 发起请求
const { data: res } = await uni.$http.get('/home/swiperdata')
// 3.2 请求失败
if (res.meta.status !== 200) {
return uni.showToast({
title: '数据请求失败!',
duration: 1500,
icon: 'none',
})
}
// 3.3 请求成功,为 data 中的数据赋值
this.swiperList = res.message
},
},
3.使用腾讯官方出的第三方库实现小程序所有API 的 Promise 化
npm i --save miniprogram-api-promise
下载完成,我们不能直接使用这个包,而是需要再次重新构建npm包(建议在构建前先删除原有的 miniprogram_npm,
然后再点击工具,构建 npm;
如果删除了 miniprogram_npm
目录,构建还是失败,需要把 node_modules
、miniprogram_npm
删除以后,重新安装包,重新安装以后,再次进行构建 )
三个步骤实现
//1.在小程序入口文件中调用一次 promisifyAll()方法
import { promisifyAll } from 'miniprogram-api-promise'
//2.声明一个常量,为一个空对象
const wxp = wx.p = {}
//3.调用 promisifyAll()方法
promisifyAll(wx, wxp)
-
我们在
wx
全局对象上定义一个属性p
让他和wxp
指向同一个空对象 -
promisifyAll
: 做的事就是将wx
拥有的属性方法都copy
并改造了一份给了wxp
这个对象 -
这样wxp和wx.p就都指向了同一个对象
//使用 async getInfo () { const { data: res } = await wx.p.request({ url: 'https://www.escook.cn/api/get', method: 'GET', data: { name: 'zs', age: 19 } }) // res 处理 console.log(res) }