防抖
使用場景:如搜索框,用戶在輸入的時候使用change事件去調用搜索,如果用戶每一次輸入都去搜索的話,就會消耗很大的服務器資源。如果每次用戶停止輸入后,延遲超過一定時間時,才去請求服務器的話,會節省服務器資源,提升用戶體驗。
原理:事件回調函數在一段時間(300毫秒)后才執行,如果在這段時間內再次調用則重新從0開始計算到300毫秒的時間,當預定的時間內沒有再次調用該函數,則執行事件回調函數
代碼示例:
/**
* 防抖
* @param {Function} func 要執行的回調函數
* @param {Number} wait 延時的時間
* @param {Boolean} immediate 是否立即執行
* @return null
*/
let timeout;
export function Debounce(func, wait=300, immediate = false) { // 清除定時器 if (timeout !== null) clearTimeout(timeout); // 立即執行,此類情況一般用不到 if (immediate) { var callNow = !timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) typeof func === 'function' && func(); } else { // 設置定時器,當最后一次操作后,timeout不會再被清除,所以在延時wait毫秒后執行func回調方法 timeout = setTimeout(function() { typeof func === 'function' && func(); }, wait); } }
在vue封裝並在main.js注冊全局,頁面調用如下:
<template>
<el-input style="width:160px;" placeholder="請輸入內容" @input="setValueNull" v-model="query.name" clearable @clear="setValueNull"></el-input>
</template>
<script>
export default { methods:{ //監聽用戶輸入值變化,延遲調用請求函數(getTableListData) setValueNull(){ this.debounce(this.getTableListData) } } } </script>
節流
使用場景:鼠標不斷點擊觸發,mousedown(單位時間內只觸發一次)
原理:單位時間內連續觸發,但是只會執行一次,比如事件在300秒內不斷觸發點擊事件,那么只會執行一次,到下一個300s開始計時的時候,就會在下一個300s內再執行一次;也就是說600s連續觸發事件但是只會執行2次。
代碼示例:
/**
* 節流
* @param {Function} func 要執行的回調函數
* @param {Number} wait 延時的時間
* @param {Boolean} immediate 是否立即執行
* @return null
*/
let timer, flag;
export function throttle(func, wait = 300, immediate = true) { if (immediate) { if (!flag) { flag = true; // 如果是立即執行,則在wait毫秒內開始時執行 typeof func === 'function' && func(); timer = setTimeout(() => { flag = false; }, wait); } } else { if (!flag) { flag = true // 如果是非立即執行,則在wait毫秒內的結束處執行 timer = setTimeout(() => { flag = false typeof func === 'function' && func(); }, wait); } } };
結語
他們的區別在於,使用時間戳實現的節流函數會在第一次觸發事件時立即執行,以后每過 wait 秒之后才執行一次,並且最后一次觸發事件不會被執行;而定時器實現的節流函數在第一次觸發時不會執行,而是在 wait秒之后才執行,當最后一次停止觸發后,還會再執行一次函數。
希望對大家學習有幫助,能力有限,如果有錯誤的歡迎指出,共同進步。