天天看點

微信小程式學習:網絡請求封裝實戰

前言部分

小程式的網絡請求是很簡單的,一個request方法就可以實作,但是我們的小程式可能不隻有幾個網絡請求。是以我們不能在每個頁面都配置一波參數寫一套請求(代碼比較多并且都是重複的,重複代碼的出現就說明你需要抽離封裝了),是以我也簡單的封裝了一下,我封裝了兩種方式:

  1. 就是正常的抽離js檔案,然後定義方法實作調用,傳回背景傳回的資料給page。
  2. 用到了一個新的東西,就是es6中的class,也就是累的概念,因為我本身是android程式員,是以對class比較熟悉,是以有單獨寫了這種方式。

内容部分

實作部分也就是貼個代碼出來而已,因為這個太簡單沒啥東西好說的,如果說的就是一些注意的事項了,比如配合法的域名位址,比如請求頭的正确,比如資料傳回的處理。

####第一種方式實作:

var _header = { "Content-Type": "application/json"}
//get請求
function sendGet(url, data = {}) {
  var header = this._header = { "Content-Type": "application/json" }
  return sendRequest(url, data, header, 'GET')
}
//post請求
function sendPost(url, data = {}) {
  var header = this._header = { "Content-Type": "application/x-www-form-urlencoded" }
  return sendRequest(url, data, header, 'POST')
}
//網絡請求的工具類
function sendRequest(url, data = {}, header = this._heade, method = 'get') {
  console.log("url::" + url + data + header);

  return new Promise((resolve, reject) => {
    wx.request({
      url: url,
      data: data,
      method: method,
      header: header,
      dataType:'json',//預設也是json的,這裡可以改成其他的
      success: function (res) {
        console.log("success");
        if (res.statusCode === 200) {
          //200: 服務端業務處理正常結束
          resolve(res)
        } else {
          reject(res)
        }
      },
      fail: function (res) {
        reject(res)

      }
    })
  })
//這裡暴露兩個方法就行了
module.exports = {
  sendGet,
  sendPost,
}
           

上面就是最簡單的網絡請求了,其實更類似于一個工具的方法,其實我們可以加入更多的東西,如資料的緩存,傳回code統一碼校驗,傳回的錯誤統一進行處理等。上面用到了一個異步的關鍵字Promise,如 java中一樣的原理網絡請求中也需要在一個異步環境中進行。

使用就很簡單了,直接引入這個js檔案就可以了啊

然後通過netUtil來調用内部的方法即可,然後就可以處理資料了

netUtil.sendPost(api.GetTooken, params)
      .then((res) => {
        console.log(res);
        console.log('開始儲存')
        var nowTime = Date.parse(new Date());       
      })
           
  • 注意一點,我們進行封裝後,其實是可以直接傳回data資料的,因為我們已經對code在封裝中進行了處理。是以上面的res其實應該對應的是res.data資料。但是前提是你提前做了這地方的處理。

####第二種方式實作:

這種方式我封裝的就更詳細了一些,像在android中一樣把所有的請求子位址都放到一起(api.js),把所有的都放到其一起(allrequest.js),這樣看起來就更像在寫android代碼了。

這裡涉及到三個js檔案,分别上面提到的api.js,allrequest.js和request.js下面來貼個代碼啦。

const API_BASE_URL = 'https://aip.baidubce.com/';

module.exports = {
  GetTooken: API_BASE_URL + 'oauth/2.0/token', //擷取token
  GetImageInfor: API_BASE_URL + 'rest/2.0/ocr/v1/numbers', //擷取圖檔的資訊

}
           

上面api.js的内容,下面是allrequest.js,這裡我就隻傳回了data資料了,所有使用的時候要注意,應該是直接使用data.參數來擷取資料了,看代碼:

import request from './request.js'
import api from './api.js'

class allrequest{
  constructor() {
    this._request = new request
    this._request.setErrorHandler(this.errorHander)
  }
  /**
     * 統一的異常處理方法
     */
  errorHander(res) {
    console.error(res)
  }
  /**
   * 擷取token
   */
  getToken(params={}) {
    console.log("params::"+ params);
    return this._request.sendPostRequest(api.GetTooken, params).then(res => res.data)
  }

  getCardInforFromImage(params = {}, access_token = '') {//+"?access_token=" + access_token
    console.log("access_token::" + access_token);
    return this._request.sendPostRequest(api.GetImageInfor + "?access_token=" + access_token, params).then(res => res.data)

  }
  
}

export default allrequest //class提供出去(暴露出來)
           

request.js中比較簡單和上面的utils很相似,

/**
 * 基礎網絡請求
 */
class request{

  constructor() {
    this._header = {}
  }

  /**
 * 設定統一的異常處理,比如登陸狀态校驗
 */
  setErrorHandler(handler) {
    this._errorHandler = handler;
  }
//get請求
  sendGetRequest(url, data = {}) {
    this._header = { 'Content-Type': 'application/json' }
    return this.sendRequest(url, data, this._header, 'GET')
  }
//post請求
  sendPostRequest(url, data = {}) {
    this._header = { "Content-Type": "application/x-www-form-urlencoded" }
    return this.sendRequest(url, data, this._header,'POST')
  }


//網絡請求的工具類
  sendRequest(url, data = {}, header=this._header,method = 'GET') {
    wx.showLoading({
      title: '資料加載中...',
    });
    console.log("url::" + url);
    return new Promise((resolve, reject) => {
      var that =this ;
      console.log("url::" + url);

      wx.request({
        url: url,
        data: data,
        method: method,
        header: header,
        success: function (res) {
          wx.hideLoading()
          console.log("success");
          if (res.statusCode === 200) {
            //200: 服務端業務處理正常結束
            resolve(res)
          } else {
             //200以外的code可以單獨處理了
            if (that._errorHandler != null) {  
              that._errorHandler(res)
            }
            reject(res)
          }
        },
        fail: function (res) {
          wx.hideLoading()
             //200以外的code可以單獨處理了
            if (that._errorHandler != null) {  
              that._errorHandler(res)
            }
          reject(res)
        },
        complete:function(res){
          wx.hideLoading()
        }
      })
    })
  }
}

export default request

           

代碼很簡單吧,就不多說什麼了啊,直接使用即可。

展示一下調用吧:

const app = getApp();//直接把上面的_allrequest初始化在app.js中了,這樣調用更友善一些了。

getNetworkToken:function(){

var params = {
      //參數
    }
    app._allrequest.getToken(params)
      .then(res=>{
        util.fromJsonToBean(res)
        that.setData({
          token_infor: util.fromJsonToBean(res)
        })    
        console.log(that.data.token_infor.access_token)

        //對象指派
      console.log('開始儲存::' + res)
        var nowTime = Date.parse(new Date());
        nowTime = nowTime / 1000;
        wx.setStorage({
          key: 'access_token',
          data: res.access_token,
          success: function (res) {
            console.log('異步儲存成功,取出資料指派' + res.data)
          },
          fail: function (res) {
            console.log('儲存失敗' + res.data)
          }
        }),
          
    })
    .catch(res=>{
      console.log('catch::' + res)
      wx.showToast({
        title: '出錯了!',
        icon: 'none'
      })
    })
  }
           

app.js中就兩行代碼,如下:

import allrequest from './utils/allrequest.js'//引入
_allrequest: new allrequest()
//初始化,要在App({ _allrequest: new allrequest() })根目錄中

           

###總結部分

小程式總的來說上手比較容易,但是問題和限制都很多,我們在編碼過程中總會碰到,但是大多數網上都是用解決方案,還有就是可以參照前端的來寫,畢竟小程式來源就是前端吧。

有問題歡迎糾正,謝謝啦

如果對你有幫助就點個贊把。