回答
分析
什么是防抖?
将n秒内连续触发的事件,以最后1次事件触发事件为准,来执行回调函数。
重点:触发后计时清除。
例如:电梯5秒后会关门开始运作,如果有人进来,等待5秒,5秒之内又有人进来,5秒等待重新计时。直至超过5秒,电梯才开始运作。
手写防抖
// 使用setTimeout,clearTimeout实现
let timeout: any;
function debounce(fn: Function, wait: number) {
clearTimeout(timeout);
timeout = setTimeout(() => fn(), wait);
}
// test 3次输出间隔时间为3s
function fn() {
console.log(new Date().getSeconds(), "done");
}
fn();
for (let i = 0; i < 100; i += 1) {
debounce(fn, 3000);
}
setTimeout(() => {
debounce(fn, 3000);
}, 3001);
// 使用setTimeout,clearTimeout实现,并且将timeout放在函数内
function debounce(fn: Function, wait: number): Function {
let timeout: any;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => fn(), wait);
};
}
// test 3次输出间隔时间为3s
function fn() {
console.log(new Date().getSeconds(), "done");
}
let doFn = debounce(fn, 3000);
fn();
for (let i = 0; i < 100; i += 1) {
doFn();
}
setTimeout(() => {
doFn();
}, 3001);
什么是节流?
将n秒内连续触发的事件,以第1次事件触发时间为准,执行回调函数。
重点:触发后计时器不清除。
例如:电梯等第一个人进来之后,5秒后准时运作,不等待,若5秒内还有人进来,也不重置。
手写节流
// 使用setTimeout,一个标记变量实现
let able: boolean = true;
function throttle(fn: Function, wait: number) {
if (able) {
able = false;
setTimeout(() => {
fn();
able = true;
}, wait);
}
}
// test 输出2次,每次间隔3s
function fn() {
console.log(new Date().getSeconds(), "done");
}
for (let i = 0; i < 100; i += 1) {
throttle(fn, 3000);
setTimeout(() => {
throttle(fn, 3000);
}, 2000);
}
setTimeout(() => {
throttle(fn, 3000);
}, 3001);
// 使用setTimeout,一个标记变量实现,并将标记变量放在函数内
function throttle(fn: Function, wait: number): Function {
let able: boolean = true;
return function () {
if (able) {
able = false;
setTimeout(() => {
fn();
able = true;
}, wait);
}
};
}
// test 输出2次,每次间隔3s
function fn() {
console.log(new Date().getSeconds(), "done");
}
let doFn = throttle(fn, 3000);
for (let i = 0; i < 100; i += 1) {
doFn();
setTimeout(() => {
doFn();
}, 2000);
}
setTimeout(() => {
doFn();
}, 3001);