大家好,我是编程小6,很高兴遇见你,有问题可以及时留言哦。
微信小程序几乎所有的 API 都是采用回调的形式,很容易陷入“回调地狱”,完全享受不到“现代化”的异步编程 Promise、async/await 所带来的优势。
我们可以对微信小程序的 API Promise 化。
// 封装
export const getImageInfo = (src) => {
return new Promise((success, fail) => wx.getImageInfo({ src, success, fail }))
}
// 使用
const getBg = getImageInfo(bgUrl)
const getAvatar = getImageInfo(avatarUrl)
Promise.all([getBg, getAvatar]).then(([bg, avatar]) => {
// ...
})
进一步的,我们可以将一些常用的 API 进行封装:
// utils/promisify.js
/** * 获取图片信息,网络图片需先配置 download 域名才能生效。 * @param {String} src */
export const getImageInfo = (src) => {
return new Promise((success, fail) => wx.getImageInfo({ src, success, fail }))
}
/** * 保存图片到系统相册 * @param {Object} options */
export const saveImageToPhotosAlbum = (options) => {
return new Promise((success, fail) => wx.saveImageToPhotosAlbum({ ...options, success, fail }))
}
// ...
在生产中,推荐直接使用 npm 包 miniprogram-api-promise,其原理也是使用 Promise 对 API 进行了一次封装:
源码见 node_modules/miniprogram-api-promise/src/promise.js
npm install --save miniprogram-api-promise
import { promisifyAll, promisify } from 'miniprogram-api-promise';
// promisify all wx's api
const wxp = {}
promisifyAll(wx, wxp)
console.log(wxp.getSystemInfoSync())
wxp.getSystemInfo().then(console.log)
wxp.showModal().then(wxp.openSetting())
// compatible usage
wxp.getSystemInfo({success(res) {console.log(res)}})
// promisify single api
promisify(wx.getSystemInfo)().then(console.log)
wx.request
封装wx.request
是微信小程序最常用的 API 之一,请求的参数较多,请求结束后的操作又是通过回调函数来完成的,多有不便。
下面对该 API 进行封装,使其支持 Promise:
// utils/request.js
/** * promisify wx.request * @param {String} baseURL 域名 * @param {String} url 请求路径 * @param {Object} data 请求参数 * @param {String} method 请求方法 */
class Request {
constructor(params) {
this.withBaseURL = params.withBaseURL
this.baseURL = params.baseURL
}
get(url, data) {
return this.request('GET', url, data)
}
post(url, data) {
return this.request('POST', url, data)
}
request(method, url, data) {
return new Promise((resolve, reject) => {
wx.request({
method,
data,
url: this.withBaseURL ? this.baseURL + url : url,
header: getApp().globalData.getHeader(),
success: (res) => resolve(res),
fail: (err) => reject(err),
})
})
}
}
export default new Request({
withBaseURL: true,
baseURL: getApp().globalData.host,
})
为了便于管理,我们往往会将项目中使用到的 HTTP 请求放到一起进行维护:
// apis/user.js
import request from '../utils/request'
export const addUser = (data) => request.post('/user/add', data)
export const getUserList = (data) => request.get('/user/list', data)
export const getUserInfo = (data) => request.get('/user/info', data)
// apis/product.js
import request from '../utils/request'
export const addProduct = (data) => request.post('/product/add', data)
export const getProductList = (data) => request.get('/product/list', data)
export const getProductDetail = (data) => request.get('/product/detail', data)