之前準備面試、看面經的時候,總會在內心罵,怎麼這麼多沙雕題目,這不是特地爲難我胖虎嗎
參加工做一年多了,發現不少面試題在工做中真的會明的暗的碰到。
能讓我等菜鳥提早知道這麼多概念,爲咱們指明debbug的方向,真是煞費了前人的一番苦心呀。css
這兩天遇到一個bug正好是利用節流的思想解決的,趁此機會正好把我對防抖節流思想的理解和應用整理一下,寫出了,但願能在工做和麪試中幫到你們html
防抖(debounce)和節流(throttle)很容易搞混,定義極其晦澀。所以咱們先從應用場景入手vue
在輸入文字的時候咱們進行某些處理,若是直接綁定處理函數,則每次輸入都會處理一次,形成性能浪費,咱們實際但願的是用戶輸入完了或者暫時輸入完了咱們再去處理,因此須要給定一個延遲時間,而後若是一直輸入咱們一律不斷去刷新這個延遲時間,直到中止輸入了再延遲處理ios
debounce函數挺簡單的,就是一個延遲執行,和刷新延遲功能,用Js的定時器和清除定時器很容易搞定,寫個超級簡單的版本面試
未防抖:<input type="text" oninput="handleInput()"> 防抖處理後:<input type="text" oninput="debounce(handleInput,300)()">
function debounce (fn,delay){ return function () { fn.tid && clearTimeout(fn.tid) fn.tid=setTimeout(fn,delay) } }
登陸按鈕,用戶登陸的時候點一下,假設報錯,帳號密碼錯誤
若是用戶手賤,一直狂點,會一直出提示,須要優化一下,先看下效果未使用節流:重複動做忒多
未使用節流:動做必定時間內只執行一次
element-ui
怎麼實現throttle(fn,delay)這個函數呢,單位時間內只能執行一次,換句話說當前執行的時候與前一次執行時間差必須大於delay才讓執行
咱們要保存上一次執行時間,咋保存呀?經過閉包
寫個超級簡單的,網上看了其餘幾我的的,好像和我不太同樣if後面還跟了個else,使單位時間後還會執行一次,這個就看我的需求啦哈哈哈,主體邏輯絕壁是我這個,你們放心大膽抄,原創
axios
throttle(fn,interval){ let lastTime = new Date().getTime()//閉包保存上一次時間,注意這個函數執行的時候LastTime就存在了,因此通常點擊的時候再觸發,fn基本會執行,也就是先執行一次,而後單位時間執行一次 return function () { let currentTime = new Date().getTime() if(currentTime-lastTime>interval){ fn() lastTime = currentTime } } }
完整代碼後端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入組件庫 --> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script> </head> <body> <div id="app"> 未節流:<el-button @click="handleLogin">login</el-button><br/><br/><br/> 節流:<el-button @click="throttleHandleLogin">login</el-button> </div> <script > new Vue({ el: '#app', data: function(){ return { throttleHandleLogin: this.throttle(this.handleLogin,2000) } }, methods: { handleLogin(){ this.$message({message:'帳號密碼錯誤',type:'error'}) }, throttle(fn,interval){ let lastTime = new Date().getTime() return function () { let currentTime = new Date().getTime() if(currentTime-lastTime>interval){ fn() lastTime = currentTime } } } } }) </script> </body> </html>
問你們一個問題,爲何我會把throttleHandleLogin寫在data裏面?寫在methods裏面行不行?想知道答案的點贊留言
閉包
看起來防抖節流都是解決動做重複觸發產生的性能問題的,可是他們的原理是不一樣的
debounce 是延遲執行,刷新延遲(理論上若是我一直動是否是能夠一直不執行?)
throttle 是馬上執行,間隔執行,(單位時間確定得執行,應該不會有人會無聊到把間隔時間設置爲無限長吧)
因此區別能夠記成,當動做一直持續下去,函數會不會執行。debounce不會,throttle會app
仍是記不住區別的記使用場景吧
如今運用咱們所學解決上個星期我遇到的一個場景
我在axios裏面有個響應攔截器,遇到後端返回的狀態碼爲xx(沒有權限)會跳到登陸頁,報錯沒有權限
可是有個問題,在某些頁面我會不止發一個請求,每一個請求都會受到沒有權限的響應引發報錯,因此跳到登陸頁我會受到N個沒有權限的提示
怎麼作?用debounce仍是throttle?
我用的throttle解決的,3秒內若是是權限問題,只讓報一次錯
//fn是權限錯誤的相關邏輯 const throttlefn = throttle(fn,3000,{trailing:false}) service.interceptors.response.use( async res => { if (!res.data) return null const { data: { msg, status } } = res switch (status) { case OK:... case NOT_LOGIN:case LoginFailed:case InvalidRole:case INVALID_PWD: throttlefn(msg) break case NONE_DATA:... default:... } },...)
今天關於節流防抖的優化就分享到這了。因爲技術有限,若是閱讀中發現有什麼錯誤,請在留言指出 若是你以爲本文對你有很大的幫助,求點贊,求收藏,求打賞,大家的支持是做者寫做的最大動力!