<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何優(yōu)雅的解決按鈕”重復點擊“問題

          共 2380字,需瀏覽 5分鐘

           ·

          2020-12-22 22:48

          選擇“置頂或者星標”

          你的關注意義重大!


          作者: 匿名


          一、這個問題怎么解決呢?

          簡單點,使用一個lock標記,在請求發(fā)出時上鎖,上鎖后就不可以再發(fā)請求,可以在請求結束后解鎖:
          let clickButton = (function () {  let lock = false  return function (postParams) {    if (lock) return    lock = 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 = false  return function (...args) {    if (lock) return    lock = true    let 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?//?假設有一些檢測表單的操作,檢查不通過則直接返回  // 返回promise  return 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()) // 請求結束解鎖})button.addEventListener('click', clickButton)

          普通場景下還是自動解鎖比較簡單,因為可能有多個條件分支,手動解鎖需要在每一個返回的地方都調(diào)用done。

          關注數(shù):10億+?文章數(shù):10億+
          粉絲量:10億+?點擊量:10億+

          ?


          懸賞博主專區(qū)請掃描這里


          喜愛數(shù):?1億+?發(fā)帖數(shù):?1億+
          回帖數(shù):?1億+?結貼率:?99.9%


          —————END—————



          喜歡本文的朋友,歡迎關注公眾號?程序員哆啦A夢,收看更多精彩內(nèi)容

          點個[在看],是對小達最大的支持!


          如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~

          瀏覽 40
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕一区二区无码成人 | 五月开心婷婷 | 日本一级视频免费看 | 亚洲精品一区二区三区2023年最新 | 免费做爱网站在线观看 |