8.9防抖节流
['10','10','10','10','10'].map(parseInt);
// [10, NaN, 2, 3, 4]
//隐式转换和parseint的参数问题
#### 节流
1. 函数节流:限制一个函数在一定的时间内只能执行一次
一定时间限制一个动作只执行一次
1. 需要节流的原因:一些事件比如mousemove scroll不做限制的话会触发的很频繁,如果里面有回调函数就会一直被触发,如果操作dom就很耗性能,还有重复调用ajax不仅造成数据混乱还有网络拥塞
2. 实现思路:主要是通过settimeout定时器设置延时时间
4. 代码:
//封装,第一次不会执行,有定时器 function throttle (method,delay) { //method是要执行的函数,delay是间隔时间 //1、设置定时器 let timer = null //2、返回一个节流函数 return function () { //取出this和参数,因为settimeout this是全局 let that = this, params = arguments //判断上一个定时器是否执行完毕 if(!timer) { //定义定时器 timer = setTimeout(function () { //执行函数 method.apply(that,params) },delay) } } } 第一次会执行,第一次间隔肯定大于delay function throttle (method,delay) { let time = 0 return function () { let cur = +New Date() if(cur - time > delay) { //执行函数 method.apply(that,params) time = cur } } }
5. 时分函数,分批创建
```javascript
var timeChunk = function (ary, fn, count) {
var t;
var start = function () {
for (var i = 0; i < Math.min(count || 1, ary.length); i ++) {
var obj = ary.shift();
fn(obj);
}
}
return function () {
t = setInterval (function () {
if (ary.length === 0) { //如果全部节点都已经被创建好
return clearInterval(t);
}
start();
}, 200); //分批执行的时间间隔,也可以用参数的形式传入
};
};
6. 使用场景:懒加载、滚动条、搜索、防止高频点击提交
http://c.biancheng.net/view/5761.html
https://segmentfault.com/a/1190000019577510
#### 防抖
1. 同上
2. 原理:触发事件之后n秒内也只会执行一次,如果在n秒内再次出发就重新计算执行时间,比如:连续触发只执行最后一次 例子坐公交车
3. 目的:任务频发触发的情况下,只有任务触发的间隔超过一段时间间隔才会触发,如果一直触发就一直不会完成任务
4. 代码
```javascript
function debounce (method,interval) {
//interval是间隔时间
let time = null
return function () {
clearTimeout(time)
let that = this, params = argumnets
time = setTimeout ( () => {
method.apply(that,params)
},interval)
}
}
5. 应用:搜索框搜索输入。只需用户最后一次输入完,再发送请求,手机号、邮箱验证输入检测,窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
6. 比较:节流侧重一段时间执行一次,防抖侧重的是在一定间隔时间一直触发只执行最后一次
7. 都可以通过使用 `setTimeout` 实现。目的都是降低回调执行频率。节省计算资源。
8. 实验代码
function handle() {
console.log(Math.random())
}
let n = 0
function f() {
console.log('次数'+ ++n)
}
//window.addEventListener('mousemove',handle)
//window.addEventListener('mousemove',throttle(handle,3000))
window.addEventListener('mousemove',debounce(handle,3000))
/* window.onresize = throttle(f, 1000); */
/* window.onresize = f */
window.onresize = debounce(f, 1000);