百舸爭流小程序 總結(jié) (一)

開始

對(duì)于創(chuàng)維俱樂部2019-2020完成的小程序,進(jìn)行總結(jié),主要講解解決實(shí)際問題的過程以及思路。
努力對(duì)代碼進(jìn)行高度封裝,保證小程序運(yùn)行狀態(tài)監(jiān)控,與后臺(tái)交互能夠流暢,使得運(yùn)行邏輯清晰。

httprequest

雖然小程序本身對(duì)請求有了wx.request()的封裝,但我們在項(xiàng)目開發(fā)過程中還是對(duì)其進(jìn)行了二次封裝,根據(jù)后臺(tái)接口文檔,把部分功能進(jìn)行統(tǒng)一的封裝,努力實(shí)現(xiàn)接口可擴(kuò)展性強(qiáng),對(duì)請求的業(yè)務(wù)分離清晰,保證小程序請求過程能夠完整監(jiān)聽,避免網(wǎng)絡(luò)不暢通,多次點(diǎn)擊造成堵塞等。

首先,根據(jù)需要請求不同的數(shù)據(jù)類型,并且需要加入鑒權(quán)的sessionId封裝出一個(gè)httprequest

import getSessionId from '../API/getSessionId'
const baseUrl = require('../config/index').baseUrl    // 服務(wù)器基址
const paramSession = [{},// 選擇不同的header
  {'content-type': 'application/json' // 不帶上session發(fā)送請求
  },
  {'content-type': 'application/x-www-form-urlencoded', // 當(dāng)發(fā)送的參數(shù)要求為int時(shí)使用
  },
  {'content-type': 'application/x-www-form-urlencoded;charset=utf-8',
  },
  {'content-type': 'application/json', // 當(dāng)請求需要帶上登錄狀態(tài)時(shí)使用
  },
  {'content-type': 'multipart/form-data; boundary=XXX', // 上傳文件時(shí)使用
  }];

/**
 * 
 * @param {*} loading 請求大型數(shù)據(jù)包標(biāo)志
 * @param {*} url 請求地址
 * @param {*} sessionChoose 根據(jù)數(shù)據(jù)類型選擇content-type
 * @param {*} sessionId 鑒權(quán)的sessionId
 * @param {*} params 發(fā)送的數(shù)據(jù)
 * @param {*} method 請求方法
 * @param {*} authCheck 是否需要鑒權(quán)的標(biāo)志
 */
function httpRequest(loading, url, sessionChoose, sessionId, params, method,authCheck=true) { // 封裝統(tǒng)一的請求方法
  if (loading == true) {          // 加載提示
    wx.showToast({
      title: '數(shù)據(jù)加載中',
      icon: 'loading'
    })
  };
    const realDeal=function() {                     // 實(shí)際處理的請求內(nèi)容
      return new Promise((resolve,reject) => {
      wx.request({
        url: baseUrl + url,
        data: params,
        dataType: "json",
        header: Object.assign(paramSession[sessionChoose],{'Cookie':sessionId||wx.getStorageSync("sessionId")}),
        method: method,
        success: res => {
          console.log(res)
          if (loading == true) {
            wx.hideToast()
          };
          const status=res.statusCode
          const isHttpSuccess=status>=200&&status<300||status===304;
          if(!isHttpSuccess){       // 返回status狀態(tài)有誤
            reject({
              msg:`httpstatus error: ${status}`,
              detail:res
            });
            return
          }
          var cookie = res.header["Set-Cookie"] // 獲取返回得到的sessionId
          if (cookie != null) {
            wx.setStorageSync("sessionId", res.header["Set-Cookie"]) // 不為空時(shí)更新sessionId
          }
          resolve(res);
        },
        fail: err => {
          console.log(err)
          if (loading == true) {
            wx.hideToast()
          }
          reject(err);
        },
        complete: () => {}
      })
    })
  };
  const httpReal=realDeal();            // 實(shí)際處理請求內(nèi)容的promise
  if(authCheck){        // 需要登錄狀態(tài)
    if(getSessionId()){
      return httpReal
    }else{
      wx.showToast({
        title: '請先登錄',
        duration: 2000
      });
      return
    }
  }else{                // 公共接口,不需登錄
    return httpReal
  }
}

export default httpRequest

檢測登錄狀態(tài)

由于我們把sessionId儲(chǔ)存在了小程序本地緩存中,那就有可能會(huì)造成一種情況:后臺(tái)的登錄信息已經(jīng)過期,但是本地緩存依然存著sessionId,所有需要鑒權(quán)的請求都無法成功。

于是,我們可以封裝一個(gè)檢測sessionId是否過期的方法,若已經(jīng)過期,則清空相關(guān)緩存,提醒用戶需要進(jìn)行登錄。

import httpRequest from '../utils/httpRequest'
function myCheckSession(callback1,callback2){ // callback2是不存在sessionId時(shí)直接運(yùn)行的回調(diào)函數(shù),可選
  let _sessionId = wx.getStorageSync('sessionId')
  let url = '/api/user/showFav/1' // 測試是否sessionId是否仍有效(登錄狀態(tài)有效)
  if(_sessionId){
    return httpRequest(false,url,4,_sessionId,null,'GET',false).then(res => {
      if(res.statusCode == 200){
        wx.setStorageSync('state', 1)
      }
      else{
        wx.removeStorageSync('userInfo')
        wx.removeStorageSync('sessionId')
        wx.setStorageSync('state',0)
        wx.showToast({
          title: res.data.message,
          icon: 'none'
        })
      }
    })
    .then(() =>{
      callback1() // 保證在使用checksession時(shí)必須先執(zhí)行該函數(shù),剩余部分放在回調(diào)函數(shù)中
    })
  }
  else{
    wx.setStorageSync('state', 0)
    if(callback2){ // 令callback2可選
      callback2() // 未登錄時(shí)直接運(yùn)行(sessionId不存在)
    }
  }
};

export default myCheckSession

接著,我們需要一個(gè)動(dòng)態(tài)獲取sessionId的方法,當(dāng)我們的請求需要鑒權(quán)的時(shí)候,就從本地緩存中取出來加到報(bào)文表頭。但是,在加入報(bào)文之前,還需要通過上方的方法鑒別sessionId是否已經(jīng)過期。為了避免頁面加載時(shí)多個(gè)請求同時(shí)獲取sessionId,導(dǎo)致引起多次鑒別sessionId是否過期,我們需要通過一個(gè)本地變量記錄查詢情況。

import myCheckSession from './myCheckSession'
let isGettingId=false

function getSessionId(){
  try{
    if(!isGettingId){                             // 避免多次獲取
      myCheckSession(function(){
        let state = wx.getStorageSync('state')    // 登錄狀態(tài),是否過期
        isGettingId=true;
        if(state){
          return wx.getStorageSync('sessionId')
        }else{                                    // 登錄過期
          return false
        }
      })
    }
  }catch(err){
    console.log(err);
    return Promise.reject(err)
  }
}

export default getSessionId

本項(xiàng)目中,我們運(yùn)用了我們自已的登錄系統(tǒng),但更好的是后臺(tái)能夠調(diào)用微信官方的登錄鑒權(quán),對(duì)其進(jìn)行封裝,獲取到我們需要的信息。在以后的項(xiàng)目開發(fā)中應(yīng)該修改這項(xiàng)標(biāo)準(zhǔn)。

cloudData

由于一些原因,后面嘗試把部分接口分離到了云開發(fā)模式,我們對(duì)云數(shù)據(jù)庫的操作進(jìn)行了簡單的封裝,如下:

const DB=wx.cloud.database()
const _=DB.command;

// 連接collection并封裝增刪改查操作
class Collection{
  constructor(name){   
    this.collection=DB.collection(name);
  }

  add(data){      // 增加一條數(shù)據(jù)
    return this.collection.add({
      data
    })            // 返回promise
  }

  get(where){     // 獲取滿足條件的數(shù)據(jù)
    return this.collection.where({
      ...where
    }).get()
  }

  getlimit(skipIndex,limitIndex){
    return this.collection.skip(skipIndex).limit(limitIndex).get()
  }

  update(where,data){
    return this.collection.where({
      ...where
    }).update({
      data
    })
  }

  remove(where){
    return this.collection.where({
      ...where
    }).remove()
  }
}

module.exports={
  Collection,
  _
}

以上封裝還不完善,以后可以再探索。

項(xiàng)目中,對(duì)于請求基礎(chǔ)的封裝如上,第一篇總結(jié)就先介紹這些。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • A類問題(技術(shù)) 1. 請談?wù)勎⑿判〕绦蜃饔茫?project.config.json 項(xiàng)目配置文件,用得最多的就...
    七月鎏金閱讀 1,951評(píng)論 0 3
  • 寫在前面 微信小程序出來也蠻久了,經(jīng)過了市場的考驗(yàn),已經(jīng)站穩(wěn)腳跟,融入到了各行各業(yè),市場需求激增打來的是開發(fā)人員的...
    月夢佳期閱讀 1,806評(píng)論 1 1
  • 網(wǎng)絡(luò)請求 wx.request(Object object) 發(fā)起網(wǎng)絡(luò)請求,最終發(fā)送給服務(wù)器的數(shù)據(jù)是 String...
    花霏花閱讀 922評(píng)論 0 3
  • 軟件框架 定義 一個(gè)軟件是由其中各個(gè)軟件模塊組成的,每一個(gè)模塊都有特定的功能,模塊與模塊之間通過相互配合來完成軟件...
    jxvl假裝閱讀 629評(píng)論 0 0
  • 久違的晴天,家長會(huì)。 家長大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒多少時(shí)間了。班主任說已經(jīng)安排了三個(gè)家長分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,818評(píng)論 16 22

友情鏈接更多精彩內(nèi)容