练练看
题目:
实现防抖和节流
分析:
防抖(debounce):触发后,等待一定时间后才执行,在等待期间再次触发将重新计算等待延时
节流(throttle):一定时间内,多次触发方法也只会执行一次
第一直觉,使用闭包和延时函数+时间戳实现
防抖:
// 常规版
debounce = (fn, delay) => {
var timer = null;
return () => {
if (timer) clearTimeout(timer); // 每次触发后重新定时
timer = setTimeout(fn, delay);
}
}
// 或
function debounce(fn, delay) {
let timer = null;
return function() {
if (timer) clearTimeout(timer);
setTimeout(fn.bind(this, arguments), delay);
}
}
// 立即执行版
// 触发后立即执行,一定时间不触发后,再次触发后会立即执行
function debounce(func, delay) {
let timer = null;
return function () {
if (timer) clearTimeout(timer);
let callNow = !timer;
timeout = setTimeout(() => timeout = null, delay);
if (callNow) func.apply(this, arguments);
}
}
节流:
// 时间戳法
function throttle(fn, delay){
var old = new Date();
return function() {
var now = new Date();
if (now - old >= delay) {
fn.apply(this, arguments);
old = now;
}
}
}
// 定时器法
function throttle(func, delay) {
let timeout = null;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args);
}, delay)
}
}
}
// 结合法
throttle = (fn, delay) => {
var timer = null;
var old = new Date();
return function() {
var now = new Date();
var remaining = delay - (now - old);
if (timer) clearTimeout(timer);
if (remaining <= 0) {
fn.apply(this, arguements);
old = now;
} else {
timer = setTimeout(fn, remaining);
}
}
}