函數的防抖和節流

定時器

  • 瀏覽器中的定時器有兩種:設置一個定時器,規定在等待時間以後執行某個方法
    • setTimeout:執行一次
    • setInterval:一直會執行下去(每間隔這麼長時間都會執行)
  • 設置定時器會有一個返回值:是一個數字,表明當前是第幾個定時器
  • clearTimeout(數字) / clearInterval(數字):清除第幾個定時器
let timer2 = setInterval(() => {}, 1000);
let timer3 = setTimeout(() => {}, 1000);
複製代碼

關閉定時器後,最好把timer= null,能夠經過timer是否爲null,判斷timer狀態;javascript

let handleTimer = document.getElementById('handleTimer'),
	timer = null,
	count = 0;

function createTimer() {
	timer = setInterval(() => {
		count++;
		console.log(count);
	}, 1000);
}
createTimer();

handleTimer.onclick = function () {
	if (timer) {
		//=>TIMER存在說明有定時器在執行,咱們讓其暫停
		clearInterval(timer);
		timer = null; //=>清除定時器後,記得把TIMER賦值爲null
		handleTimer.value = "開始";
		return;
	};
	//=>TIMER不存在:建立新的定時器
	createTimer();
	handleTimer.value = "暫停";
};
複製代碼

underscorejs.org JS類庫(提供不少項目中須要常常使用的方法)java

函數的防抖(debounce)

觸發高頻事件後n秒內函數只會執行一次,若是n秒內高頻事件再次被觸發,則從新計算時間(每次觸發事件時都取消以前的延時調用方法)瀏覽器

/* * debounce:函數防抖 * @params * func:要執行的函數 * wait:間隔等待時間 * immediate:在開始邊界仍是結束邊界觸發執行(TRUE=>在開始邊界) * @return * 可被調用的函數 * by LYR on 2019/08/21 */
function debounce(func, wait, immediate) {
	let result = null,
		timeout = null;
	return function (...args) {
		let context = this,
			now = immediate && !timeout;
		clearTimeout(timeout); 
		timeout = setTimeout(() => {
			timeout = null;
			if (!immediate) result = func.call(context, ...args);
		}, wait);
		if (now) result = func.call(context, ...args);
		return result;
	}
}

let count = 0;

function fn() {
	console.log(++count);
}
let lazyFn = _.throttle(fn, 1000);
window.onscroll = lazyFn;
複製代碼

函數的節流(throttle)

爲了縮減執行的頻率,但不像防抖同樣,必定時間內只能執行一次,而是必定時間內能執行屢次,只是執行頻率減少(每次觸發事件時都判斷當前是否有等待執行的延時函數);app

/* * throttle:函數節流是爲了縮減執行頻率,當達到了必定的時間間隔就會執行一次 * @params * func:須要執行的函數 * wait:設置的間隔時間 * @return * 返回可被調用的函數 * by LYR on 2019/08/21 */
let throttle = function (func, wait) {
	let timeout = null,
		result = null,
		previous = 0; //=>上次執行時間點
	return function (...args) {
		let now = new Date,
			context = this;
		//=>remaining小於等於0,表示上次執行至此所間隔時間已經超過一個時間間隔
		let remaining = wait - (now - previous);
		if (remaining <= 0) {
			clearTimeout(timeout);
			previous = now;
			timeout = null;
			result = func.apply(context, args);
		} else if (!timeout) {
			timeout = setTimeout(() => {
				previous = new Date;
				timeout = null;
				result = func.apply(context, args);
			}, remaining);
		}
		return result;
	};
};


let count = 0;

function fn() {
	console.log(++count);
}
let lazyFn = _.throttle(fn, 1000);
window.onscroll = lazyFn;
複製代碼
相關文章
相關標籤/搜索