微信小程式wx.request的簡單封裝

徐磊x發表於2018-05-23

這些天團隊裡開始做小程式開發了,之前沒做過,都是第一次,第一次的感覺大家都懂的。週末看了一下小程式專案的程式碼,在網路請求上發現了一些小問題,最終沒忍住想了點辦法把request封裝了一下。下面來看看吧。

看專案程式碼時發現了下面幾點問題:

  • 網路請求都寫在Page裡,每個請求都要重複的寫wx.request以及一些基礎配置;
  • 每個頁面裡都要處理相同型別的異常;
  • 後端返的http status code為200以外時,並不能直接進入fail對應函式進行處理;

針對這些問題,首先在專案目錄裡新建了一個apis的目錄,把所有與API請求的東西都放在這個目錄裡,如下圖這樣。

apis目錄結構
1. 新建一個request類,對wx.request進行簡單封裝 在request類裡做了以下幾件事:

  • 在建構函式裡建立預設請求的http header,可以在header裡配製一些內容,在對應請求方法中如果沒有設定header引數,就使用此預設header引數;
  • 以get post delete put等方法對request進行封裝,在發起網路請求不需要重複的寫wx.request({method:xxx})這些程式碼,只要呼叫getRequest、postRequest等方法就可以了;
  • 在rquest的結果返回處理函式success中,判定服務端返回的狀態程式碼,對於200狀態程式碼的按業務處理成功處理,對於非200的狀態碼按異常處理。
  • 預留統一異常處理函式處理介面,可以通過setErrorHandler來設定統一的異常處理,這樣對於一些可以統一處理的異常就不用在業務頁面裡去重複處理了,例如後端返回401的程式碼,就可以統一轉到登入頁面讓使用者登入了;
  • 此request不限定服務提供都,可以是自己開發的業務服務端,也可以用於第三方服務的呼叫;
/**
 * name: api.js
 * description: request處理基礎類
 * author: 徐磊
 * date: 2018-5-19
 */
class request {
  constructor() {
    this._header = {}
  }

/**
 * 設定統一的異常處理
 */
  setErrorHandler(handler) {
    this._errorHandler = handler;
  }

  /**
   * GET型別的網路請求
   */
  getRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'GET')
  }

  /**
   * DELETE型別的網路請求
   */
  deleteRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'DELETE')
  }

  /**
   * PUT型別的網路請求
   */
  putRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'PUT')
  }

  /**
   * POST型別的網路請求
   */
  postRequest(url, data, header = this._header) {
    return this.requestAll(url, data, header, 'POST')
  }

  /**
   * 網路請求
   */
  requestAll(url, data, header, method) {
    return new Promise((resolve, reject) => {
      wx.request({
        url: url,
        data: data,
        header: header,
        method: method,
        success: (res => {
          if (res.statusCode === 200) {
          	//200: 服務端業務處理正常結束
            resolve(res)
          } else {
          	//其它錯誤,提示使用者錯誤資訊
            if (this._errorHandler != null) {
            //如果有統一的異常處理,就先呼叫統一異常處理函式對異常進行處理
              this._errorHandler(res)
            }
            reject(res)
          }
        }),
        fail: (res => {
          if (this._errorHandler != null) {
            this._errorHandler(res)
          }
          reject(res)
        })
      })
    })
  }
}

export default request
複製程式碼

2. 新建一個agriknow類 在agriknow裡面做了以下幾件事:

  • 實現所有業務服務呼叫,如查詢所有新聞列表【getNews】,查詢所有課程列表【getCourseList】;
  • 實現統一的異常處理,並傳給request;
  • 將服務端返回的結果response轉成response.data回傳給API呼叫的地方;
/**
 * name: agriknow.js
 * description: 農知匯伺服器提供的服務
 * author: 徐磊
 * date: 2018-5-19
 */
import request from './request.js'
class agriknow {
  constructor() {
    this._baseUrl = 'https://apis.xxx.xxx.com/dev/apis/train/v1/'
    this._defaultHeader = { 'data-tupe': 'application/json' }
    this._request = new request
    this._request.setErrorHandler(this.errorHander)
  }

  /**
   * 統一的異常處理方法
   */
  errorHander(res) {
    console.error(res)
  }

  /**
   * 查詢所有新聞列表
   */
  getNews(page = 1, size = 10) {
    let data = { page: page, size: size }
    return this._request.getRequest(this._baseUrl + 'news/client', data).then(res => res.data)
  }

  /**
   * 獲取所有課程
   */
  getCourseList(page = 1, size = 10, key = null) {
    let data = key != null ? { page: page, size: size, queryValue: key } : { page: page, size: size }
    return this._request.getRequest(this._baseUrl + '/course/mobile', data).then(res => res.data)
  }
}
export default agriknow
複製程式碼

3. 函式的呼叫

  • 在app中引用argriknow
    import agriknow from './apis/agriknow.js'
    App({
      onLaunch: function () {
        // 展示本地儲存能力
        var logs = wx.getStorageSync('logs') || []
        logs.unshift(Date.now())
        wx.setStorageSync('logs', logs)
    ……
    ……
    複製程式碼
  • 定義一個型別為agriknow的屬性並例項化
    import agriknow from './apis/agriknow.js'
    App({
      onLaunch: function () {
        // 展示本地儲存能力
        var logs = wx.getStorageSync('logs') || []
        logs.unshift(Date.now())
        wx.setStorageSync('logs', logs)
    ……
    ……
      },
      agriknow:new agriknow()
    })
    複製程式碼
  • 在Page裡呼叫
    const app = getApp();
    Page({
      data: {
        courseData: [],
        page: 1,
        size: 10,
        total: 0
      },
      onLoad: function () {
      ……
      ……
        wx.startPullDownRefresh()
        this.getdataList();
      },
      //查詢課程列表
      getdataList() {
        app.agriknow.getCourseList(this.data.page++, this.data.size, '')
          .then(res => {
            wx.stopPullDownRefresh()
            let list = this.data.page > 2 ? this.data.courseData.concat(res.list) : res.list
            this.setData({
              courseData: list
            })
          })
          .catch(res => {
            wx.stopPullDownRefresh()
            wx.showToast({
              title: '出錯了!',
              icon: 'none'
            })
          })
      },
      //下拉重新整理
      onPullDownRefresh() {
        console.log("下拉重新整理");
        this.getdataList();
      },
      ……
      ……
    })
    複製程式碼

所有的東西大概就是這個樣子了,就這麼個意思,希望對大家有點用。

相關文章