用setTimeout 实现setInterval
let timer = null;
function mockSetInterval(fn, delay, ...args) {
const recurFn = function() {
timer = setTimeout(() => {
fn.apply(this, atgs);
recurFn();
}, delay);
}
recurFn();
}
function mockClearInterval(id) {
clearTimeout(id);
}
防抖和节流
防抖
-
当持续触发事件时,一定时间内没有再触发事件,事件处理函数才会执行一次,如果一定时间内多次触发事件,就会重新开始延时
-
最后一次事件触发后一定时间才会触发
适用场景
function debounce(fn, wait) {
let timer = null;
return (...args) => {
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, wait);
}
}
节流
- 当持续触发事件时,保证一段时间内只调用一次事件处理函数,当持续触发scroll事件的时候,每隔一定时间才会执行一次事件处理函数
适用场景
// 时间戳,首节流,第一次立即执行,但是停止之后,没法再次执行
function throttle(fn, interval) {
let last = 0;
return (...args) => {
let now = Date.now();
if(now - last >= interval) {
fn.apply(this, args);
last = now;
}
}
}
// setTimeout 实现,尾节流,第一次不会立即执行,最后一次还会执行
function throttle(fn, wait) {
let timer = null;
return (...args) => {
if(!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
})
}
}
}
// 结合
function throttle(fn, wait) {
let timer = null;
let last = 0;
return (...args) => {
clearTimeout(timer);
let now = Date.now();
if(now - last >= wait) {
fn.apply(this, args);
last = now;
} else {
timer = setTimeout(() => {
fn.apply(this, args);
}, wait);
}
}
}