亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

詳細分析JS函數去抖和節流

2024-05-06 16:41:17
字體:
來源:轉載
供稿:網友

本篇內容從節流和去抖的概念基礎知識講起,對JS函數做了詳細的分析,一起來看下:

1、什么是節流和去抖?

節流。就是擰緊水龍頭讓水少流一點,但是不是不讓水流了。想象一下在現實生活中有時候我們需要接一桶水,接水的同時不想一直站在那等著,可能要離開一會去干一點別的事請,讓水差不多流滿一桶水的時候再回來,這個時候,不能把水龍頭開的太大,不然還沒回來水就已經滿了,浪費了好多水,這時候就需要節流,讓自己回來的時候水差不多滿了。那在JS里有沒有這種情況呢,典型的場景是圖片懶加載監聽頁面的scoll事件,或者監聽鼠標的mousemove事件,這些事件對應的處理方法相當于水,由于scroll和mousemove在鼠標移動的時候會被瀏覽器頻繁的觸發,會導致對應的事件也會被頻繁的觸發(水流的太快了),這樣就會造成很大的瀏覽器資源開銷,而且好多中間的處理是不必要的,這樣就會造成瀏覽器卡頓的現象,這時候就需要節流,如何節流呢?我們無法做到讓瀏覽器不去觸發對應的事件,但是可以做到讓處理事件的方法執行頻率減少,從而減少對應的處理開銷。

去抖。最早接觸這個詞應該是在高中物理里面學到的,有時候開關在在真正閉合之前可能會發生一些抖動現象,如果抖動的明顯的話,對應的小燈泡可能會閃爍,把燈泡閃壞了不重要,萬一把眼睛再給閃壞了可就麻煩了,這個時候就有去抖電路的出現。而在我們的頁面里,也有這種情況,假設我們的一個輸入框,輸入內容的同時可能會去后臺查詢對應的聯想 詞,如果用戶輸入的同時,頻繁的觸發input事件,然后頻繁的向后抬發送請,那么直到用戶輸入完成時,之前的請求都應該是多余的,假設網絡慢一點,后臺返回的數據比較慢,那么顯示的聯想詞可能會出現頻繁的變換,直到最后的一個請求返回。這個時候就可以在一定時間內監聽是否再次輸入,如果沒有再次輸入則認為本次輸入完成,發送請求,否則就是判定用戶仍在輸入,不發送請求。

去抖和節流是不同的,因為節流雖然中間的處理函數被限制了,但是只是減少了頻率,而去抖則把中間的處理函數全部過濾掉了,只執行規判定時間內的最后一個事件。

2、JS實現。

前面BB了這么多,感謝你耐心的看到這里,接下來我們來自己動手看看如何實現節流和去抖。

節流:

/** 實現思路:  ** 參數需要一個執行的頻率,和一個對應的處理函數,  ** 內部需要一個lastTime 變量記錄上一次執行的時間  **/  function throttle (func, wait) {   let lastTime = null    // 為了避免每次調用lastTime都被清空,利用js的閉包返回一個function確保不生命全局變量也可以   return function () {    let now = new Date()    // 如果上次執行的時間和這次觸發的時間大于一個執行周期,則執行    if (now - lastTime - wait > 0) {     func()     lastTime = now    }   }  }

再看如何調用:

// 由于閉包的存在,調用會不一樣let throttleRun = throttle(() => {  console.log(123)}, 400)window.addEventListener('scroll', throttleRun)

這時候f瘋狂的滾動頁面,會發現會400ms打印一個123,而沒有節流的話會不斷地打印, 你可以改變wait參數去感受下不同。

但是到這里,我們的節流方法是不完善的,因為我們的方法沒有獲取事件發生時的this對象,而且由于我們的方法簡單粗暴的通過判斷這次觸發的時間和上次執行時間的間隔來決定是否執行回調,這樣就會造成最后一次觸發無法執行,或者用戶出發的間隔確實很短,也無法執行,造成了誤殺,所以需要對方法進行完善。

function throttle (func, wait) {   let lastTime = null   let timeout   return function () {    let context = this    let now = new Date()    // 如果上次執行的時間和這次觸發的時間大于一個執行周期,則執行    if (now - lastTime - wait > 0) {     // 如果之前有了定時任務則清除     if (timeout) {      clearTimeout(timeout)      timeout = null     }     func.apply(context, arguments)     lastTime = now    } else if (!timeout) {     timeout = setTimeout(() => {      // 改變執行上下文環境      func.apply(context, arguments)     }, wait)    }   }  }

這樣我們的方法就相對完善了,調用方法和之前相同。

去抖:

去抖的方法,和節流思路一致,但是只有在抖動被判定結束后,方法才會得到執行。

debounce (func, wait) {   let lastTime = null   let timeout   return function () {    let context = this    let now = new Date()    // 判定不是一次抖動    if (now - lastTime - wait > 0) {     setTimeout(() => {      func.apply(context, arguments)     }, wait)    } else {     if (timeout) {      clearTimeout(timeout)      timeout = null     }     timeout = setTimeout(() => {      func.apply(context, arguments)     }, wait)    }    // 注意這里lastTime是上次的觸發時間    lastTime = now   }  }

這時候按照之前同樣的方式調用,會發現無論怎么瘋狂的滾動窗口,只有停止滾動時,才會執行對應的事件。

去抖和節流已經有很多成熟的js進行了實現,其大致思路基本是這樣的。

 

我們再給大家分享一下網友的實現方法的代碼:

方法一

1.這種實現方式的思路很好理解:設置一個一間隔時間,比如50毫秒,以此時間為基準設置定時器,當第一次觸發事件到第二次觸發事件間隔小于50毫秒時,清除這個定時器,并設置一個新的定時器,以此類推,直到有一次事件觸發后50毫秒內沒有重復觸發。代碼如下:

function debounce(method){  clearTimeout(method.timer);  method.timer=setTimeout(function(){   method();  },50); } 

這種設計方式有一個問題:本來應該多次觸發的事件,可能最終只會發生一次。具體來說,一個循序漸進的滾動事件,如果用戶滾動太快速,或者程序設置的函數節流間隔時間太長,那么最終滾動事件會呈現為一個很突然的跳躍事件,中間過程都被節流截掉了。這個例子舉的有點夸張了,不過使用這種方式進行節流最終是會明顯感受到程序比不節流的時候“更突兀”,這對于用戶體驗是很差的。有一種彌補這種缺陷的設計思路。

方法二

2.第二種實現方式的思路與第一種稍有差別:設置一個間隔時間,比如50毫秒,以此時間為基準穩定分隔事件觸發情況,也就是說100毫秒內連續觸發多次事件,也只會按照50毫秒一次穩定分隔執行。代碼如下:

var oldTime=new Date().getTime(); var delay=50; function throttle1(method){  var curTime=new Date().getTime();  if(curTime-oldTime>=delay){   oldTime=curTime;   method();  } } 

相比于第一種方法,第二種方法也許會比第一種方法執行更多次(有時候意味著更多次請求后臺,即更多的流量),但是卻很好的解決了第一種方法清除中間過程的缺陷。因此在具體場景應根據情況擇優決定使用哪種方法。

對于方法二,我們再提供另一種同樣功能的寫法:

var timer=undefined,delay=50; function throttle2(method){  if(timer){   return ;  }  method();  timer=setTimeout(function(){   timer=undefined;  },delay); }

 

 

注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品国产电影| 日韩国产高清视频在线| 欧美裸体男粗大视频在线观看| 日韩a**站在线观看| 一区二区亚洲精品国产| 成人有码视频在线播放| 国产精品网站大全| 在线a欧美视频| 91影院在线免费观看视频| 性欧美暴力猛交69hd| 亚洲大胆人体视频| 日韩电视剧免费观看网站| 亚洲永久在线观看| 97国产精品视频人人做人人爱| 亚洲黄色av女优在线观看| 热99精品里视频精品| 亚洲精品成a人在线观看| 亚洲欧美制服中文字幕| 影音先锋日韩有码| 亚洲欧洲在线免费| 国产精品精品视频一区二区三区| 国内外成人免费激情在线视频网站| 国产精品久久久久久搜索| 亚洲精品国产精品久久清纯直播| 欧洲永久精品大片ww免费漫画| 欧美黑人狂野猛交老妇| 综合av色偷偷网| 亚洲色图综合网| 中文字幕欧美日韩| 国产成人精品av| 精品自在线视频| 国产精品99久久久久久人| 亚洲毛片在线观看.| 午夜精品一区二区三区在线| 成人情趣片在线观看免费| 国产亚洲xxx| 成人性生交大片免费看小说| 亚洲大胆美女视频| 亚洲有声小说3d| 国产精品精品久久久久久| 午夜精品久久久久久久99热| 色爱av美腿丝袜综合粉嫩av| 日韩高清电影免费观看完整版| 亚洲欧美国产制服动漫| 欧美激情第三页| 欧美亚洲激情在线| 久久亚洲欧美日韩精品专区| 亚洲精品av在线播放| 最近中文字幕日韩精品| 亚洲欧美综合区自拍另类| 91在线观看免费高清完整版在线观看| 精品免费在线视频| 91精品视频免费观看| 97视频在线观看亚洲| 欧美成人免费大片| 日韩hd视频在线观看| 日韩视频在线免费观看| 日韩精品有码在线观看| 亚洲欧美国产日韩中文字幕| 久久色精品视频| 欧美日韩亚洲精品一区二区三区| 色哟哟亚洲精品一区二区| 亚洲黄色免费三级| 国产91av在线| 欧美激情欧美狂野欧美精品| 久久夜色撩人精品| 色天天综合狠狠色| 亚洲欧美中文字幕| 精品伊人久久97| 欧美黑人性视频| 免费97视频在线精品国自产拍| 国产精品久久精品| 国产精品免费小视频| 国产男人精品视频| 日韩av在线播放资源| 国产精品自产拍在线观| 亚洲成人黄色网| 久久精品99久久香蕉国产色戒| 久久久精品2019中文字幕神马| 国产99视频在线观看| 91av福利视频| 久久亚洲综合国产精品99麻豆精品福利| 久久精品国产欧美亚洲人人爽| 日韩av在线免播放器| 国产91在线播放精品91| 亚洲一级一级97网| 美日韩精品免费视频| 日本成人在线视频网址| 中文字幕日韩av综合精品| 亚洲精品欧美极品| 国产精品久久久久久久久久久久| 欧美贵妇videos办公室| 狠狠躁夜夜躁人人爽超碰91| 日本不卡免费高清视频| 97香蕉久久夜色精品国产| 成人av在线亚洲| 久热精品视频在线观看一区| 九九热这里只有在线精品视| 亚洲天堂第一页| 色哟哟入口国产精品| 在线视频亚洲欧美| 国产精品久久久一区| 亚洲国产一区二区三区在线观看| 欧美性猛交xxxx乱大交极品| 亚洲国产成人精品电影| 亚洲欧美日韩国产精品| 中文字幕日韩av电影| 中文字幕日韩av综合精品| 亚洲小视频在线观看| 精品中文字幕视频| 国产精品国产自产拍高清av水多| 国产精品久久久久久久久久小说| 精品亚洲国产成av人片传媒| 国产综合福利在线| 亚洲第一福利网| 九九久久久久久久久激情| 日韩视频在线观看免费| 一区二区福利视频| 97香蕉超级碰碰久久免费的优势| 亚洲一区二区久久久久久久| 日韩精品中文字幕在线观看| 精品香蕉一区二区三区| 一本色道久久88综合亚洲精品ⅰ| 亚洲一区二区自拍| 欧美日韩国产成人在线观看| 国产最新精品视频| 久久91精品国产91久久跳| 91在线高清免费观看| 97视频在线观看亚洲| 久久久久亚洲精品| 在线播放国产精品| 91精品国产自产91精品| 亚洲欧美国产精品专区久久| 最新国产成人av网站网址麻豆| 久久999免费视频| 欧美在线视频免费观看| 久久久久久久久综合| 国产精欧美一区二区三区| 45www国产精品网站| 欧美精品久久久久久久| 久久精品久久精品亚洲人| 国产欧美日韩中文字幕在线| 亚洲美女喷白浆| 日韩电影中文字幕一区| 国产精品日韩欧美| 欧美精品在线看| 久久精品免费电影| 国产日韩欧美一二三区| 国产精品扒开腿爽爽爽视频| 2019中文在线观看| 亚洲热线99精品视频| 亚洲人成在线观看| 日本欧美国产在线| 色哟哟亚洲精品一区二区| 九九久久精品一区| 色噜噜狠狠色综合网图区| 成人免费视频a| 亚洲精品视频网上网址在线观看| 欧美高清视频免费观看| 欧美激情一二三| 在线观看视频亚洲| 最近2019免费中文字幕视频三| 国产91成人video| 色香阁99久久精品久久久|