優(yōu)雅解決按鈕”重復點擊“問題
加入我們一起學習,天天進步
一、這個問題怎么解決呢?
let clickButton = (function () {let lock = falsereturn function (postParams) {if (lock) returnlock = true// 假設使用axios發(fā)送請求axios.post('urlxxx', postParams).then(// 表單提交成功).catch(error => {// 表單提交出錯console.log(error)}).finally(() => {// 不管成功失敗 都解鎖lock = false})}})()button.addEventListener('click', clickButton)
當然對于button按鈕,可以使用setAttribute('disabled', xxx)和removeAttribute('disabled')來代替lock標記。
這個方案問題在于,對于每一次按鈕點擊,我們都要寫個lock標記,相當于重復的邏輯會出現(xiàn)在代碼的各個地方——是不是可以封裝一下呢?
二、封裝按鈕鎖定、解鎖邏輯
寫一個裝飾器將邏輯封裝起來:
function ignoreMultiClick(func, manual = false) {let lock = falsereturn function (...args) {if (lock) returnlock = truelet done = () => (lock = false)if (manual) return func.call(this, ...args, done)let promise = func.call(this, ...args)Promise.resolve(promise).finally(done)return promise}}
將想監(jiān)聽點擊回調(diào)函數(shù)func作為傳遞給ignoreMultiClick進行裝飾,會返回一個新的函數(shù),使用該函數(shù)作為點擊的回調(diào)事件即可。
這里同樣用了一個標記lock來上鎖,有兩種方法解鎖:
手動解鎖:可以給ignoreMultiClick傳遞一個參數(shù)manual,意思是主動調(diào)用解鎖。若該參數(shù)為truthy,則點擊事件觸發(fā)時會給原始的點擊回調(diào)func傳遞一個參數(shù)done,done是一個函數(shù),調(diào)用它可以解鎖。
自動解鎖:可以使原監(jiān)聽函數(shù)func返回一個promise,在該promise決議后自動執(zhí)行解鎖操作。因為Promise管理回調(diào)函數(shù)非常方便,并且像axios這樣非常常用的請求庫返回值本身也是一個promise,所以默認情況使用這種方式。
當然返回promise并不是必須的,有時候我們在發(fā)請求前會進行一些驗證,驗證沒通過則直接return,此時裝飾器函數(shù)也能正常處理,因為使用Promise.resolve包裹了一下promise:Promise.resolve(promise).finally(done)。
三、使用實例
自動解鎖使用例子:
let clickButton = ignoreMultiClick(function (postParams) {if (!checkForm()) return // 假設有一些檢測表單的操作,檢查不通過則直接返回// 返回promisereturn axios.post('urlxxx', postParams).then(// 表單提交成功).catch(error => {// 表單提交出錯console.log(error)})})button.addEventListener('click', clickButton)
手動解鎖:
let clickButton = ignoreMultiClick(function (postParams, done) {if (!checkForm()) return done() // 表單驗證不通過解鎖axios.post('urlxxx', postParams).then(// 表單提交成功).catch(error => {// 表單提交出錯console.log(error)}).finally(() => done()) // 請求結(jié)束解鎖})button.addEventListener('click', clickButton)
普通場景下還是自動解鎖比較簡單,因為可能有多個條件分支,手動解鎖需要在每一個返回的地方都調(diào)用done。
??愛心三連擊 1.看到這里了就點個在看支持下吧,你的「點贊,在看」是我創(chuàng)作的動力。
2.關注公眾號
程序員成長指北,回復「1」加入Node進階交流群!「在這里有好多 Node 開發(fā)者,會討論 Node 知識,互相學習」!3.也可添加微信【ikoala520】,一起成長。
“在看轉(zhuǎn)發(fā)”是最大的支持
