具体来说阐释下HDR和IIS的基本概念
1.HDR:促发低频该事件后n秒内表达式只会继续执行一场,假如n秒内低频该事件再度被促发,则再次排序天数;
经营理念:每天促发该事件时都中止以后的延后天数初始化方式
示例标识符:
/**
* @desc 表达式HDR * @param func 表达式
* @param wait 延后继续执行微秒数
* @param immediate true 表立刻继续执行,false 表非立刻继续执行
*/
function debounce(func, wait, immediate) {
let timeout; //建立两个记号用以放置计时器的codice
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout); //每当用户输入时把前两个setTimeout clear()掉
if (immediate) { //判断是否立刻继续执行
var callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait);
if (callNow) func.apply(context, args);
} else {
timeout = setTimeout(() => {
//然后又建立两个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内假如还有字符输入的话,就不会继续执行 fn 表达式
func.apply(this, arguments);
}, wait);
}
};
}
function sayHi() {
console.log(“HDR成功”);
}
var inp = document.getElementById(“inp”);
inp.addEventListener(“input”, debounce(sayHi, 2000, false)); //HDR
2.IIS:低频该事件促发,但在n秒内只会继续执行一场,所以IIS会稀释函数的继续执行频率
经营理念:每天促发该事件时都判断当前是否有等待继续执行的延后天数表达式
示例标识符:
/**
* @desc 表达式IIS
* @param func 表达式
* @param wait 延后继续执行微秒数
* @param type 1 表天数戳版,2 表计时器版 */
function throttle(func, wait, type) {
if (type === 1) {
var previous = 0;
} else if (type === 2) {
var timeout;
}
return function () {
let context = this;
let args = arguments;
if (type === 1) {
let now = Date.now();
if (now – previous > wait) {
func.apply(context, args);
previous = now;
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args);
}, wait);
}
}
};
}
function sayHi(e){
console.log(e.target.innerWidth,e.target.innerHeight);
}
window.addEventListener(resize,throttle(sayHi,1000,1))
总结:debounce和throttling 各有特点,在不同 的场景要根据需求合理的选择策略。假如该事件促发是低频但是有停顿时,可以选择debounce; 在该事件连续不断低频促发时,只能选择throttling,因为debounce可能会导致动作只被继续执行一场,界面出现跳跃。
(PS:做个简单的分享,有不足的地方,欢迎指出,有分享才会有进步!!!)
参考文章:
https://github.com/mqyqingfeng/Blog/issues/22