JS之節流和防抖

概述

在平時的開發中,常常會聽到兩個差很少很相近的詞。節流(throttle)和防抖(debounce)。這是兩個相似又有些不一樣的優化方案。react

節流:在指定時間以內,讓函數只觸發一次。
防抖:對於必定時間段的連續的函數調用,只讓其執行一次。ajax

兩個方法在underscore.js中都已經實現了。本文將會重點說明兩個函數的應用場景和背後的原理。瀏覽器

應用場景

節流

throttle在英語裏的意思是節流閥,顧名思義,設置一個閥值(制定一個時間),在這個閥值或者時間以內,函數只會執行一次。閉包

舉個例子,咱們執行頁面滾動的時候,好比在react裏面,可能每次滾動都會觸發一次render,這樣嚴重影響性能,甚至會形成瀏覽器卡死。若是咱們設置一個300ms的時間閥,那麼在這段時間內,滾動時候只會觸發一次render.app

一樣的,當咱們拖拽某個元素的時候,會每次判斷mousemove時跟位置相關的信息,每次都會執行相關的計算和判斷,這種狀況就和滾動時候同樣,若是設置一個時間閥,那麼就能夠避免因爲大量執行事件計算而形成的性能降低。函數

防抖

我本身的理解,防抖的意思能夠認爲是,阻止連續的抖動(所謂的事件觸發),也就是說,咱們用防抖來讓那些連續觸發的事件只觸發一次。性能

好比,當咱們對一個文本框進行輸入的時候,在react中,每次都會觸發onChange事件,咱們可能在每次事件裏發送ajax請求,判斷輸入的用戶名是否曾經註冊過,這種狀況下咱們使用防抖,能夠保證只會在最後一次onChange事件纔會觸發ajax請求。優化

實現原理

節流this

節流實現起來很好理解,設置一個bool值,在時間閥以內,根據這個bool來判斷是否執行函數。code

function throttle(fn,times = 300){
    let bool = true
    return function(){
        if(!bool){
            return false
        }
        bool = false
        setTimeout(()=>{
            bool = true
            fn.apply(this,arguments)
        },times)
    }
    
}

防抖

防抖實現起來的思路是,用閉包保存執行的函數,屢次執行的時候把上一個執行的函數清除掉,而後再次建立一個新的函數。這樣在間隔時間內還有事件觸發的話,不會執行以前的函數,這麼一來,函數真正的執行就是最後一次事件觸發。

function debounce(fn,times){
    let timeout = null
    return function(){
        clearTimeout(timeout)
        timeout = setTimeout(()=>{
            fn.apply(this,arguments)
        },times)
    }
}

總結

以上只是很簡單的寫了一下節流和防抖的原理,在underscore.js裏,實現起來更加複雜,可是背後的原理核心就是上邊代碼寫的。二者都是在密集調用的過程當中靈活使用setTimeout函數來對頻繁觸發的事件進行控制和優化。

相關文章
相關標籤/搜索