微信小程序 API promisify 及后端接口统一管理

61,452 阅读2分钟

API promisify

微信小程序几乎所有的 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 }))
}

// ...

miniprogram-api-promise

在生产中,推荐直接使用 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)

参考链接

  1. RequestTask | 微信开放文档:developers.weixin.qq.com/miniprogram…
  2. API Promise化 | 微信开放文档:developers.weixin.qq.com/miniprogram…