微信小程序開發(fā)點擊按鈕常見問題解決
微信小程序開發(fā)點擊按鈕已經(jīng)是當下最熱門的話題,下面將從多方面來談微信小程序開發(fā)點擊按鈕相關(guān)的內(nèi)容。
在互聯(lián)網(wǎng)應用中,我們經(jīng)常用到的場景,比如用戶點擊某個按鈕,觸發(fā)的操作會和后臺api進行數(shù)據(jù)交互,生成一些記錄,比如下單購買。如果后臺api請求比較慢,而客戶端體驗又做得不到位,導致用戶以為沒點擊到或者是頁面假死,在上次請求還沒處理完,就再次點擊按鈕。這樣會導致某個操作生成多次記錄,導致一些異常的bug。
很顯然,后臺的api在這方面是需要做好處理。然而,面對用戶,我們需要更好的體驗,可以在客戶端去避免這些問題,前置地解決問題。
最近聽產(chǎn)品經(jīng)理常說,用戶點擊某個按鈕多次,后臺還沒處理完導致多筆記錄生成,我們需要在用戶點擊后跳轉(zhuǎn)到一個新的頁面,其實這根本不是跳頁問題,是程序問題。如果程序員真這么干,是不是要下崗了。
以前偷懶的時候,在前端我們可能會這么處理:
var getUserDataFlag = false;
function getUserData() {
if (getDataFlag) {
return;
}
getDataFlag = true;
$.ajax({
url: '/xxx/getUser',
success: function () {
getUserData = false;
//todo
},
error: function () {
getUserData = false;
}
})
}
//當接口很多的時候,我們的代碼就變成這樣
var getUserAssetFlag = true;
function getUserAsset() {
if (getDataFlag) {
return;
}
getDataFlag = true;
$.ajax({
url: '/xxx/getUserAsset',
success: function () {
getUserAssetFlag = false;
//todo
},
error: function () {
getUserAssetFlag = false;
}
})
}
上面的例子你會發(fā)現(xiàn),當接口越來越多,維護請求狀態(tài)的變量將會越來越多,并且當存在依賴時,維護成本更高,也更容易出錯。
如何優(yōu)雅地解決這樣的問題,其實封裝一下請求就能簡單又能自動地處理這個問題。
下面我們以微信小程序請求后臺數(shù)據(jù)為例解說:
import {isObject} from './util'
let Promise = require('../libs/bluebird.min')
let requestList = {} //api請求記錄
// 將當前請求的api記錄起來
export function addRequestKey (key) {
requestList[key] = true
}
// 將請求完成的api從記錄中移除
export function removeRequestKey (key) {
delete requestList[key]
}
//當前請求的api是否已有記錄
export function hitRequestKey (key) {
return requestList[key]
}
// 獲取串行請求的key,方便記錄
export function getLockRequestKey (data) {
if (!isObject(data)) {
return data
}
let ajaxKey = 'lockRequestKey:'
try {
ajaxKey += JSON.stringify(data)
} catch (e) {
ajaxKey += data
}
return ajaxKey
}
//根據(jù)請求的地址,請求參數(shù)組裝成api請求的key,方便記錄
export function getRequestKey (data) {
if (!isObject(data)) {
return data
}
let ajaxKey = 'Method: ' + data.method + ',Url: ' + data.url + ',Data: '
try {
ajaxKey += JSON.stringify(data.data)
} catch (e) {
ajaxKey += data.data
}
return ajaxKey
}
//所有與服務(wù)器進行http請求的出口
export function http (data) {
if (!isObject(data)) {
throw Error('ajax請求參數(shù)必須是json對象: ' + data)
}
data.method = (data.method || 'GET').toUpperCase()
//下面5行是對所有http請求做防重復請求處理,后面單獨分享原理
let ajaxKey = getRequestKey(data)
if (hitRequestKey(ajaxKey)) {
throw Error('重復提交請求:' + ajaxKey)
}
addRequestKey(ajaxKey)
//bluebird.js包裝成promisepromise api
return new Promise(function (resolve, reject) {
//通過wx.request api 向服務(wù)器端發(fā)出http請求
wx.request({
url: data.url,
data: data.data,
method: data.method,
header: data.header || {'Content-Type': 'application/json'},
complete: function (res) {
// 請求完成,釋放記錄的key,可以發(fā)起下次請求了
removeRequestKey(ajaxKey)
let statusCode = res.statusCode
if (statusCode === 200 || statusCode === 304) {
return resolve(res.data)
}
return reject(res)
}
})
})
}
//通用get請求方法
export function httpGet (data) {
return http(data)
}
//通用post請求方法
export function httpPost (data) {
data.method = 'POST'
return http(data)
}
// 該方法適用于串行請求的api
export function lockRequest (data, fn) {
let ajaxKey = getLockRequestKey(data)
if (hitRequestKey(ajaxKey)) {
throw Error('重復提交請求:' + ajaxKey)
}
addRequestKey(ajaxKey)
return new Promise(function (resolve, reject) {
fn(data)
.then(function (data) {
removeRequestKey(ajaxKey)
return resolve(data)
})
.catch(function (error) {
removeRequestKey(ajaxKey)
return reject(error)
})
})
}
整體思路就是統(tǒng)一所有請求的入口,然后以API請求的地址,參數(shù),請求類型(get,post)等組裝為唯一key緩存起來。這樣就能知道某個請求的完成狀態(tài),當?shù)诙€相同的請求過來時,我們可以根據(jù)上一次的狀態(tài)來判斷下一步的操作。
-
微信小程序商城系統(tǒng)開發(fā)其實很簡單
微信小程序商城系統(tǒng)開發(fā)其實很簡單,只需要五步就可以完成,整個過程包括開發(fā)、上線、發(fā)布都可以輕松搞定...詳情
第二部分:如何開通一個小商店