詳細聊一聊js防抖節(jié)流到底是什么
前言
防抖和節(jié)流,這是前端防止用戶頻繁調用同一個接口的方法,比如短時間重復點擊上傳同一個文件,短時間重復點擊提交同一個評論,異步的操作還沒給你帶來反饋,于是你重復上傳了多個文件,重復提交了多個評論。
本文以常見的使用場景與解決方案,一篇教會你如何使用防抖節(jié)流。
場景
為了例子更加簡單,我們就用延遲來模擬一個后端接口返回的過程。
<body> <button onclick="comment()">發(fā)表評論</button> <script> const commentApi = () => { // 我們使用延遲模擬異步請求 setTimeout(() => { const div = document.createElement('div') div.innerText = '本人到此一游' document.body.appendChild(div) }, 1000) } const comment = () => { // 請求發(fā)布評論Api commentApi() } </script> </body>
以上是一個發(fā)表評論的例子,由于接口一秒后才會響應評論反饋到界面上。
用戶本意只是發(fā)布一條評論,但是由于接口需要響應時間,他以為自己的第一次點擊沒有生效于是就多點擊了兩次,結果顯而易見,就是非用戶本意的發(fā)布了三條一樣的評論。
我們希望的是用戶不要在請求還在進行的時候,頻繁的重復發(fā)送請求。這時候就需要防抖節(jié)流了。
防抖
核心
- 設置延遲,短時間高頻率觸發(fā)只有最后一次觸發(fā)成功
解釋
防抖指的是設置延時器,比方說我點擊之后設置一個1s的延遲,1s后開始上傳。
如果在1s之中再次點擊該事件,那么這個延遲被清除,重置1s的延遲,也就是還沒開始上傳你得重新等待1s。
也就是無論你如何一直亂點,也只有你停止點擊后的最后一次點擊會成功。
修復場景例子
快速點擊幾次,還是只會發(fā)送一條評論。
但是缺點就是用戶得到響應的時間更久了,得要算上延遲加上接口的響應。
<body> <button onclick="comment()">發(fā)表評論</button> <script> const commentApi = () => { // 我們使用延遲模擬異步請求 setTimeout(() => { const div = document.createElement('div') div.innerText = '本人到此一游' document.body.appendChild(div) }, 1000) } let later const comment = () => { // 如果已經設置過延遲請求,則重置延遲 if (later) { clearTimeout(later) } later = setTimeout(() => { commentApi() }, 1000) } </script>
所以防抖一般也不完全適合此類型的場景,它更適合需要一定操作結束之后再執(zhí)行的場景,比如請你輸入一段話,輸入結束之后再進行請求,當然不希望你在輸入的過程中就開始請求了,于是設置防抖,直到發(fā)覺你停止輸入了才開始請求。
節(jié)流
核心
- 設置狀態(tài)鎖,短時間高頻率觸發(fā)只有第一次會觸發(fā)成功
解釋
節(jié)流是設置狀態(tài)鎖,比如設置一個key作為鎖,鎖一開始的狀態(tài)是關閉的,我們將key設置為false。
當你點擊的時候,會對key進行判斷,如果發(fā)現(xiàn)key為false,未上鎖,那么開始請求,并且與此同時給key上鎖,將flag設置為true。
然后這時候你繼續(xù)點擊請求的時候,同樣要判斷key,發(fā)現(xiàn)上鎖了,你怎么點擊也沒用。
然后什么時候再將鎖關閉呢?在你接口返回給前端,提示你已經上傳完畢了之后,再將key關閉置為false,就可以再次提交請求了。
修復場景例子
快速點擊幾次,還是只會發(fā)送一條評論。只有一條請求發(fā)布成功之后,才能夠發(fā)布第二條請求,對于該場景十分合適。
<body> <button onclick="comment()">發(fā)表評論</button> <script> let key = false const commentApi = () => { setTimeout(() => { const div = document.createElement('div') div.innerText = '本人到此一游' document.body.appendChild(div) // 請求結束,解鎖 key=false }, 1000) } const comment = () => { // 未上鎖開始執(zhí)行 if (!key) { // 請求開始,上鎖 key = true commentApi() } } </script> </body>
總結
函數(shù)防抖:將多次操作合并為一次操作進行。原理是維護一個計時器,規(guī)定在delay時間后觸發(fā)函數(shù),但是在delay時間內再次觸發(fā)的話,就會取消之前的計時器而重新設置。這樣一來,只有最后一次操作能被觸發(fā)。
函數(shù)節(jié)流:使得一定時間內只觸發(fā)一次函數(shù)。原理是通過判斷是否有延遲調用函數(shù)未執(zhí)行。
區(qū)別: 函數(shù)節(jié)流不管事件觸發(fā)有多頻繁,都會保證在規(guī)定時間內一定會執(zhí)行一次真正的事件處理函數(shù),而函數(shù)防抖只是在最后一次事件后才觸發(fā)一次函數(shù)。 比如在頁面的無限加載場景下,我們需要用戶在滾動頁面時,每隔一段時間發(fā)一次 Ajax 請求,而不是在用戶停下滾動頁面操作時才去請求數(shù)據。這樣的場景,就適合用節(jié)流技術來實現(xiàn)。
到此這篇關于js防抖節(jié)流到底是什么的文章就介紹到這了,更多相關js防抖節(jié)流內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
js setTimeout()函數(shù)介紹及應用以倒計時為例
setTimeout() 方法用于在指定的毫秒數(shù)后調用函數(shù)或計算表達式,下面有個倒計時的示例,需要的朋友可以學習下2013-12-122019 年編寫現(xiàn)代 JavaScript 代碼的5個小技巧(小結)
這篇文章主要介紹了2019 年編寫現(xiàn)代 JavaScript 代碼的5個小技巧,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-01-01JavaScript實現(xiàn)計數(shù)器基礎方法
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)計數(shù)器的基礎方法2017-10-10
,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下