JavaScript节流和防抖
两者都是为了减少请求次数。
防抖
例子:假如快手上有个视频封面很好看,我要点进去,但是一激动点了两次,这时候如果没有做任何处理的话我是进了两次详情页。所以需要防止你手抖重复进入详情页。
如果没有处理,可能会出现什么情况,卡顿,导致用户体验不太好,重复请求接口,加大了服务器压力等等情况。
HTML
<ul id="list">
<li id="item">我是视频封面</li>
</ul>
JS
var item = document.getElementById("item");
item.addEventListener("click", debounch(detail, 2000));
// 进入详情
function detail () {
console.log("进入详情");
}
// 封装防抖
function debounch (fn, wait) { // fn表示需要执行的方法,wait表示setTimeout需要的时间。
var t = null;
return function () {
if (t) clearTimeout(t); // 如果有以前的定时器需要先清理
if(!t) fn(); // 如果没有定时器则执行函数,这种写法第一次不会有延迟,如果需要第一次有延迟的注释这一行,将fn()写入定时器中
t = setTimeout(function () {
// fn();
t = null;
}, wait)
}
}
节流
例子:游戏平A打人,假如我的攻速是一秒一下,在十秒内我狂按了一百下,虽然我按了一百下但是游戏中我只能打出去十下。
HTML
<button id="btn">平A</button>
JS
var btn = document.getElementById("btn");
btn.addEventListener("click", throttle(hit, 1000));
// 平A
function hit () {
console.log("平A");
}
// 封装节流
function throttle (fn, wait) {
var begin = 0; // 开始时间
return function () {
// 为什么这里的this指向的不是window
var cur = new Date().getTime(); // 获取当前时间戳
if (cur - begin > wait) {
fn();
begin = cur;
}
}
}
这里我并没有写call()与apply去改变它的this指向,因为我也有疑问,为什么return的匿名函数的this指向的不是window?