【微信小程序】用Promise封裝wx.request

前言

微信小程序官方提供了 wx.request(OBJECT) 方法來實現網絡請求。javascript

小程序網絡請求的缺點

小程序框架自帶的網絡請求和Ajax請求很是類似都是異步請求,請求參數中須要送入url、method、data、header等參數,還要設置success成功的回調函數和fail失敗的回調函數,當無數個success的嵌套再嵌套,致使每一次看代碼邏輯都要費勁千辛萬苦。java

這就是傳說中的回調地獄,那有什麼辦法去解決呢?固然有,那就是Promise。ios

與微信原生請求庫對比有哪些優勢?

  1. api方法調用,你能夠實現跟Axios同樣的調用
  2. 默認和自定義的請求成功、失敗和完成的回調處理
  3. 可設置請求失敗自動從新請求的次數
  4. 能夠防止重複提交網絡請求
  5. 每一個請求設定requestCode
  6. 設置接口鑑權和token刷新操做

api.js

咱們將實例封裝到api.js中,全局引入調用,跟app.js分開,互不干擾,相互獨立小程序

// 獲取小程序全局配置(變量、函數等)
const app = getApp()
// 定義網絡請求API地址
const baseURL = '這裏爲你的api地址'
// 封裝網絡請求開始
const http = ({url,data,method,...other} = {}) => {
    // 添加請求加載等待
    wx.showLoading({
        title: '加載中...'
    })
    // Promise封裝處理
    return new Promise((resolve, reject) => {
        wx.request({
            // 請求地址拼接
            url: baseURL+url,
            data: data,
            // 獲取請求頭配置
            header: getHeader(),
            method: method,
            ...other,
            // 成功或失敗處理
            complete: (res) => {
                // 關閉等待
                wx.hideLoading()
                // 進行狀態碼判斷並處理
                if(res.statusCode === 204){
                    resolve(res)
                }else if (res.statusCode === 401) {
                    // 檢測到狀態碼401,進行token刷新並從新請求等操做
                    refreshToken().then(()=>_refetch(url,data,method)).then(resolve)
                }else if(res.data.code !== 200){
                    // 獲取後臺返回報錯信息
                    let title = res.data.err_msg
                    // 調用全局toast方法
                    showToast(title)
                }else if(res.data.code === 200){
                    resolve(res)
                }else {
                    reject(res)
                }
            }
        })
    })
}
// 添加請求toast提示
const showToast = title =>{
    wx.showToast({
        title: title,
        icon: 'none',
        duration: 1500,
        mask:true
    });
}

// 進行url字符串拼接
const getUrl = url => {
  if (url.indexOf('://') == -1) {
    url = baseURL + url
  }
  return url
}
//獲取用戶userToken
function getHeader(){
    // 判斷登陸token是否存在
    if(wx.getStorageSync('userToken')){
        // 獲取token並設置請求頭
        var token = wx.getStorageSync('userToken')
        let auth = {
            'Authorization': token.token_type +" "+ token.access_token
        }
        return auth
    }
}
// 重構請求方式
const _fetch = (content) => {
    return http({
        url:content.url,
        data:content.data,
        method:content.method
    })
}
// 添加刷新以後的操做處理方法
const refreshToken = () => {
    return new Promise((resolve, reject) => {
        // 獲取token
        var token = wx.getStorageSync('userToken')
        // 設置請求data
        let params = {
            refresh_token:token.refresh_token
        }
        // 進行token刷新請求
        wx.request({
            url: getUrl('/app/connect/refresh'),
            data:params,
            // 設置請求header 鑑權
            header: {
                'Authorization': token.token_type +" "+ token.access_token
            },
            method:'post',
            // 請求響應處理
            complete: (res) => {
                if(res.data.code === 200 ){
                    // 全局存儲token
                    app.globalData.usertToken = res.data.data
                    // Storage存儲token
                    wx.setStorage({
                        key:"userToken",
                        data:res.data.data,
                        // 存儲成功處理
                        success:function(){
                           resolve()
                        }
                    })
                }
            }
        })
    });
}
const _refetch = (url,data,method) => {
    return http({
        url:url,
        data:data,
        method:method
    })
}
//除開上面的調用方式以外,你也能夠使用下面的這些方法,只須要關注是否傳入method
const _get = (url, params = {}) => {
    return http({
        url,
        params
    })
}
const _post = (url, params = {}) => {
    return http({
        url,
        params,
        method: 'post'
    })
}
const _put = (url, params = {}) => {
    return http({
      url,
      params,
      method: 'put'
    })
}
const _delete = (url, params = {}) =>{
    return http({
      url,
      params,
      method: 'delete'
    })
}
module.exports = {
  baseURL,
  refreshToken,
  _fetch,
  _refetch,
  _get,
  _post,
  _put,
  _delete
}

複製代碼

調用方式

post

const api = require('../utils/api.js')

api._fetch({
    url: '/list',
    data:data,
    method:'post'
}).then(function (res) {
    console.info(res)
}).catch(function (error) {
    console.log(error);
});
複製代碼

get

const api = require('../utils/api.js')

api._fetch({
    url: '/list',
    data:data,
}).then(function (res) {
    console.info(res)
}).catch(function (error) {
    console.log(error);
});

複製代碼

結語

封裝一個好的功能集(全局方法庫),能更好的保證代碼的一致性和工做的高效。微信小程序

相關文章
相關標籤/搜索