溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微信小程序網(wǎng)絡(luò)層封裝的實(shí)現(xiàn)(promise, 登錄鎖)

發(fā)布時間:2020-10-25 10:35:04 來源:腳本之家 閱讀:192 作者:海洋餅干 欄目:web開發(fā)

一、對小程序的request的封裝

寫過小程序的應(yīng)該知道,微信的request不封裝基本上不能用,寫的顯的太冗長,而且是回調(diào)式的,回調(diào)地獄什么的就不說了,可讀性差。

下面是我的封裝代碼,順便支持一下promise。

function baseRequest({ url, method, header, data, complete }, resolve, reject) {
 wx.request({
 url,
 method,
 header,
 data,
 success: function (res) {
  // 需要判斷服務(wù)器code的用這一段
  // 我司服務(wù)器返回0表示真正的成功,其他code表示各種錯誤碼
  // if (res.data.code === 0) {
  // resolve(res)
  // } else {
  // reject(res)
  // }
  resolve(res)
 },
 fail: function (res) {
  reject(res)
 },
 complete: function (res) {
  complete(res)
 }
 })
}

function requestPromise( options ) {
 let req = new Promise((resolve, reject) => {
 baseRequest(options, resolve, reject)
 })
 return req
}

function get(options) {
 options.method = 'GET'
 return requestPromise(options)
}

function post(options) {
 options.method = 'POST'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options)
}

function put(options) {
 options.method = 'PUT'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options)
}


module.exports = {
 get,
 post,
 put
}

如何使用:

1. 將上面的代碼寫到一個獨(dú)立的文件里,我的命名為network.js。

2. 然后將其綁定到全局的 wx 對象身上。 wx.Network = require('./network.js')。(在app.js里面綁定)

3. 實(shí)例如下

wx.Network.get({
 url: 'xxx.xxx.xxx', // 請求路徑
 data: {
  a: "a" // 參數(shù)列表
 }
 }).then(res => {
  console.log("請求成功")
 }).catch(res => {
  console.log("請求失敗") 
 })

二、登錄鎖

基本的request請求封裝完了后,還有一些特殊的需求,比如

1. 在首頁我會進(jìn)行登錄, 登錄后獲得token, 然后我拿著token去請求其他需要token才可以請求的接口 (比如個人購物信息)

2. 這個時候一種做法是登錄完成前不進(jìn)行需要token的請求,并且有蒙板進(jìn)行攔截操作(正在登錄ing...)

3. 對于我公來說這種方法有一個致命的弊端,就是在高并發(fā)的情況下,服務(wù)器的壓力很大,首頁的登錄接口很慢才有返回(進(jìn)首頁即自動登錄),這個時候,用戶看到的界面就是loading,而且可能時間比較長,如果用戶對你的產(chǎn)品粘性不高,絕大部分人直接就走了

4. 為了優(yōu)化這種情況下的用戶體驗(yàn),我們?nèi)嫒∠说卿浀膌oading,替換成了“登錄鎖”的形式

5. 效果為未登錄調(diào)用需要token的接口時,不請求,直到登錄完成后才會請求

6. 即如果這個請求需要token,那么先判斷有沒有登錄,如果沒有登錄,啟動定時器一段時間后(200ms),再次判斷,如果已經(jīng)登錄,發(fā)出請求,如果沒有,重復(fù)以上操作

加了登錄鎖后的代碼如下: ( 添加了新的 wait 函數(shù),調(diào)用get,post,put時增加第二個參數(shù),表示是否需要token )

function baseRequest({ url, method, header, data, complete }, resolve, reject) {
 wx.request({
 url,
 method,
 header,
 data,
 success: function (res) {
  // 需要判斷服務(wù)器code的用這一段
  // 我司服務(wù)器返回0表示真正的成功,其他code表示各種錯誤碼
  // if (res.data.code === 0) {
  // resolve(res)
  // } else {
  // reject(res)
  // }
  resolve(res)
 },
 fail: function (res) {
  reject(res)
 },
 complete: function (res) {
  complete(res)
 }
 })
}

function wait(options, needToken, resolve, reject) {
 if (needToken) {
 var token = wx.getStorageSync('token')
 if (!token) {
  setTimeout(() => {
  wait.apply(null, arguments)
  }, 200)
 } else {
  if (!options.header) {
  options.header = {}
  }
  options.header["token"] = token
  baseRequest(options, resolve, reject)
 }
 } else {
 baseRequest(options, resolve, reject)
 }
}

function requestPromise( options, needToken = true ) {
 let req = new Promise((resolve, reject) => {
 wait(options, needToken, resolve, reject)
 })
 return req
}

function get(options, needToken) {
 options.method = 'GET'
 return requestPromise(options, needToken)
}

function post(options, needToken) {
 options.method = 'POST'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options, needToken)
}

function put(options, needToken) {
 options.method = 'PUT'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options, needToken)
}


module.exports = {
 get,
 post,
 put
}

如何使用:(使用方式和上面一樣,只是調(diào)用的時候多一個參數(shù))

1. 將上面的代碼寫到一個獨(dú)立的文件里,我的命名為network.js。

2. 然后將其綁定到全局的 wx 對象身上。 wx.Network = require('./network.js')。(在app.js里面綁定)

3. 實(shí)例如下

wx.Network.get({
 url: 'xxx.xxx.xxx', // 請求路徑
 data: {
  a: "a" // 參數(shù)列表
 }
 }, true // 增加第二個參數(shù),true表示需要token, false表示不需要
 ).then(res => {
  console.log("請求成功")
 }).catch(res => {
  console.log("請求失敗") 
 })

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI