微信小程序網(wǎng)絡(luò)層封裝的實(shí)現(xiàn)(promise, 登錄鎖)
一、對小程序的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. 這個時(shí)候一種做法是登錄完成前不進(jìn)行需要token的請求,并且有蒙板進(jìn)行攔截操作(正在登錄ing...)
3. 對于我公來說這種方法有一個致命的弊端,就是在高并發(fā)的情況下,服務(wù)器的壓力很大,首頁的登錄接口很慢才有返回(進(jìn)首頁即自動登錄),這個時(shí)候,用戶看到的界面就是loading,而且可能時(shí)間比較長,如果用戶對你的產(chǎn)品粘性不高,絕大部分人直接就走了
4. 為了優(yōu)化這種情況下的用戶體驗(yàn),我們?nèi)嫒∠说卿浀膌oading,替換成了“登錄鎖”的形式
5. 效果為未登錄調(diào)用需要token的接口時(shí),不請求,直到登錄完成后才會請求
6. 即如果這個請求需要token,那么先判斷有沒有登錄,如果沒有登錄,啟動定時(shí)器一段時(shí)間后(200ms),再次判斷,如果已經(jīng)登錄,發(fā)出請求,如果沒有,重復(fù)以上操作
加了登錄鎖后的代碼如下: ( 添加了新的 wait 函數(shù),調(diào)用get,post,put時(shí)增加第二個參數(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í)候多一個參數(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í)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js實(shí)現(xiàn)StringBuffer的簡單實(shí)例
下面小編就為大家?guī)硪黄猨s實(shí)現(xiàn)StringBuffer的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
JavaScript asp.net 獲取當(dāng)前超鏈接中的文本
今天用到,不會。網(wǎng)上找到一個方法,趕快記下來??梢垣@取超鏈接的鏈接文本。2009-04-04
js的window.showModalDialog及window.open用法實(shí)例分析
這篇文章主要介紹了js的window.showModalDialog及window.open用法,實(shí)例分析了window.showModalDialog與window.open方法的定義、功能與使用技巧,需要的朋友可以參考下2015-01-01
JS 創(chuàng)建對象的模式實(shí)例小結(jié)
這篇文章主要介紹了JS 創(chuàng)建對象的模式,結(jié)合實(shí)例形式總結(jié)分析了JS 創(chuàng)建對象的各種常用模式,包括工廠模式、構(gòu)造函數(shù)模式、原型模式、組合構(gòu)造和原型模式、動態(tài)原型模式、寄生構(gòu)造函數(shù)模式、穩(wěn)妥構(gòu)造模式等,需要的朋友可以參考下2020-04-04
用JavaScript實(shí)現(xiàn)一個代碼簡潔、邏輯不復(fù)雜的多級樹
這篇文章主要介紹了用JavaScript實(shí)現(xiàn)一個代碼簡潔、邏輯不復(fù)雜的多級樹,需要的朋友可以參考下2014-05-05
javascript實(shí)現(xiàn)判斷鼠標(biāo)的狀態(tài)
這篇文章主要介紹了javascript實(shí)現(xiàn)判斷鼠標(biāo)的狀態(tài)的相關(guān)代碼,十分簡單實(shí)用,有需要的小伙伴可以參考下。2015-07-07

