debounce: 函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 实现。
使用场景:
对于键盘事件,当用户输入比较频繁的时候, 可以通过debounce合并键盘事件处理
对于ajax请求的情况,例如当页面下拉超过一定返回就通过ajax请求新的页面内容,这时候可以通过debounce合并ajax请求事件
/**
* 函数防抖
* 函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 实现
*/
/**
* @param {*} fn 执行的方法
* @param {*} delay 延迟时间
*/
function debounce(fn, delay){
let timer = null;
return function(){
const context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout( () => {
fn.apply(context, args);
}, delay);
}
}
throttle: 在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能。
使用场景:
对于键盘事件,当用户输入非常频繁, 但是我们又必须要在一定时间内(阙值)内执行处理函数的时候, 就可以使用throttle
例如一些网页游戏的键盘事件;
对于鼠标移动和窗口移动,鼠标的移动和窗口的滚动会带来大量的事件,但是在一段时间内又必须看到页面的效果
例如对于可以拖动的div,如果使用debounce,那么div会在拖动停止后一下子跳到目标位置,这就需要使用throttle;
/**
* 利用settimeout来实现 函数节流
* @param {*} func 执行的方法
* @param {*} wait 间隔的时间
*/
function basicThrottle(fn, wait){
let timer;
let firstTime = true;
return (...args) => {
const context = this;
if(firstTime) {
fn.apply(context, args);
return firstTime = false;
}
if(timer) return;
timer = setTimeout( () =>{
fn.apply(context, args);
timer = null;
}, wait);
}
}
/**
* 利用 时间戳来实现函数节流
* +new Date()将会调用Date.prototype上的valueOf方法,
* 根据 MDN Date.prototype.value方法等同于 Date.prototype.getTime()
*/
function throttle(fn, wait){
let last = 0;
return () => {
const current_time = +new Date();
if(current_time - last > wait){
fn.apply(this, arguments);
last = +new Date()
}
}
}
// 需要被节流的 函数
function scrollHandler (arg) {
console.log(`${arg}--被执行了`);
}
// 被节流的函数 -- 节流限制: 每 1000 毫秒执行一次
const throttleFunc = throttle(scrollHandler, 1000);
let i = 0;
// 模拟 页面滚动事件
setInterval(() => {
console.log(`${i} --- 进来了,但是不知道有没有执行`);
throttleFunc(i++);
}, 10);