第一题:节流函数

在规定的时间内,只执行一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function throttle(fn: (m: number) => void, pars: any, time: number) {
let lastTime: number = null;
let context = this;
return function () {
let nowTime = Date.now();
if (nowTime - lastTime > time || lastTime === null) {
fn.apply(context, pars);
lastTime = nowTime;
}
};
}

export function fn(m: number) {
console.log("节流函数" + m);
}

setInterval(throttle(fn, [123], 3000), 1000); // 每三秒输出一次

节流函数是为了防止一个函数在短时间内重复调用,其本质是解决性能问题。

节流函数的使用场景有以下几种:

  • 窗口 resize;
  • 鼠标 mousemove;
  • 滚轮相关事件;
  • 其他;

第二题:SWR 的过期验证

一个过期验证函数,其参数是url和过期时间,在过期时间内,则返回旧的数据,超出过期时间,请求返回新数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function stale(time: number) {
let timer = true;
let data;

return function () {
if (timer) {
data = "获取数据";
setTimeout(() => {
timer = true;
}, time);
timer = false;
} else {
data = "返回缓存";
}
return data;
};
}

const test = stale(5000);

console.log(test()); // 获取数据
console.log(test()); // 返回缓存

利用函数闭包,通过调用其返回的函数,维护函数stale中的数据。

这个并没有传入 url,通过为data赋值,模拟从请求拿到数据。

useMount

创建一个自定义 hook,参数为一个函数,功能是在组件挂载时执行一次,重新渲染时不执行。

1
2
3
4
5
export default function useMount(fn: () => void) {
React.useEffect(() => {
fn();
}, []);
}

useEffect()的依赖数组为空时,其第一个参数只会在组件挂载时执行一次。

console.log()

当 console.log()的参数为函数时,会输出什么

1
2
3
4
5
export default function test(m: () => void) {
console.log(m);
}

test(() => console.log(1)); // [Function]

输出的是参数的类型。

其他相关——防抖函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function debounce(fn: () => void, pars: [], time: number) {
let timer = null;

return function () {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
fn.apply(this, pars);
}, time);
};
}

function fn() {
console.log("防抖函数");
}

setInterval(debounce(fn, [], 3000), 5000);

这个方法的重点是,它在用户不触发事件的时,才触发动作,并且抑制了本来在事件中要执行的动作,常见的场景:

  • 表单输入
  • 其他

节流防抖的区别

节流:在函数执行触发fn()后一定时间内不会再次触发

防抖:在函数执行后等待一定时间触发fn()