函数的防抖和节流

定时器

  • 浏览器中的定时器有两种:设置一个定时器,规定在等待时间以后执行某个方法
    • 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;
复制代码
相关文章
相关标签/搜索