Skip to content
This repository has been archived by the owner on Mar 29, 2020. It is now read-only.

Latest commit

 

History

History
235 lines (205 loc) · 7.01 KB

README.md

File metadata and controls

235 lines (205 loc) · 7.01 KB

minapp-api-promise

npm Build Status license JS Gzip Size

微信小程序所有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一定会执行')
  }
}

你也可以使用promisethen/catch写法:

onLoad () {
  WXP.request({
    url: 'http://baidu.com'
  }).then(resp => {
    console.log('success信息:', resp)
  }).catch(errorMesg => {
    console.log('fail信息:', errorMesg)
  })
}

其他所有的微信小程序原生api(具备异步回调函数的api)使用方法同上

进阶说明

interceptor 拦截器

可以使用全局拦截器对原生API接口进行拦截
⚠️注意:这里不仅仅局限于Http请求的拦截!
比如某些页面需要登录才能看,我们可以拦截路由,在跳转前判断跳转的页面是否需要登录:

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语法