函数节流
本来打算从零写一个,不过意外看到一篇好文,下面就根据他的思路来实现一个节流,JavaScript专题之跟着 underscore 学节流
前言
节流有两种实现,第一种使用定时器,另外一种则是根据时间戳,判断两次执行的时间间隔,下面简单些一下这两种的实现。
- 定时器
function throttle(fn, time) {
let timing = null;
return function(...rest) {
if(!timing) {
timing = setTimeout(() => {
timing = null;
fn.apply(this, rest);
}, time);
}
};
};
- 时间戳
function throttle (fn, time) {
let times = 0;
return function (...rest) {
const s = time - (new Date().getTime() - times)
if (s <= 0) {
times = new Date().getTime();
fn.apply(this, rest);
}
};
};
下面就是将两者结合起来
节流
// 节流
// initial初始立即执行,front最后执行一次
function throttle (fn, time, { initial = true, front = false } = {}) {
// 上一次执行时间
let times = 0;
// 定时器
let timing = null;
function next (...args) {
// 判断条件,如果不是初始执行,改用定时器方法执行
if (!initial && !times) {
times = new Date().getTime();
}
const now = time - (new Date().getTime() - times);
// now > time是判断更改系统时间的边界问题,now正常情况下,肯定小于time
if (now <= 0 || now > time) {
if (!timing) {
clearTimeout(timing);
timing = null;
}
times = new Date().getTime();
fn.apply(this, args);
// 清理一下内存
if (!timing) {
args = null;
}
} else if (!timing && front) {
timing = setTimeout(() => {
timing = null;
times = initial ? 0 : new Date().getTime();
fn.apply(this, args);
if (!timing) {
args = null;
}
}, time);
}
}
// 取消
next.cancel = function () {
clearTimeout(timing);
timing = null;
// 为0即可,上面有初始判断条件
times = 0;
};
return next;
};
注意
上面有两个参数,但是不能同时设置为false