-
这个也是一个经常会碰到的问题
(可应用于交互频繁的一个地方, 例如表单的交互)
节流与防抖
指触发事件后在规定时间内回调函数只能执行一次,如果在规定时间内又触发了该事件,则会重新开始算规定时间。
相同:在不影响客户体验的前提下,将频繁的回调函数,进行次数缩减.避免大量计算导致的页面卡顿.
防抖:
不同:防抖是将多次执行变为最后一次执行,节流是将多次执行变为在规定时间内只执行一次.
四个字总结就是 延时执行
网上有这个比喻:函数防抖就是法师发技能的时候要读条,技能读条没完再按技能就会刷新技能,重新进行读条。
===================================================================
引用场景: 游戏的刷新率, 例如(60HZ王者荣耀);
. canvas的画笔功能
/**
*
* @param {Function} fn [执行的函数]
* @param {Number} gapTime [设置间隔时间]
*/
function throttle(fn,gapTime){
let lastTime=null
return ()=>{
let nowTime=+new Date() //转变为数字
if(nowTime-lastTime>gapTime){
fn()
lastTime=nowTime
}
console.log('-----测试-----');
}
}
let fn=()=>console.log('hello world');
setInterval(throttle(fn,2000),500)//setInter 模拟点击
- input输入框输入停下了一会才会显示
- 这个可能就像我的学习一样吧-,-
// 防抖
/**
*
* @param {Function} fn [函数]
* @param {Number} gapTime [时间]
*/
function debounce(fn, gapTime){
let time=null
return ()=>{
let that=this
let args=arguments
if(time){
console.log('---没有执行哦----');
clearTimeout(time)
time=null
}
time=setTimeout(()=>{
fn.apply(that,args)
},gapTime)
}
}
let fn=()=>console.log('hello world');
setInterval(debounce(fn,2000),500)//不用执行hello world
注: 需要掌握apply改变this指向, arguments(闭包
的知识也在其中)
11/11 最新版补充:
针对于防抖函数(可以分为后执行,与先执行两个版本)
// 防抖(没有参数处理)
function debounce(fn, wait) {
var timeout = null;
return function() {
if(timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
console.log(Math.random());
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));
------------------------------------------
//先执行
function debounce_1(fn,wait){
let timeout
let that=this
return function(){
let args = [].slice.call(arguments);
if(timeout) clearTimeout(timeout);
let callNow = !timeout;
timeout = setTimeout(()=>{
timeout = null;
},wait)
if(callNow) fn.apply(that,args);
}
}
// 处理函数
function handle() {
console.log(Math.random());
}
// 滚动事件
window.addEventListener('scroll', debounce_1(handle, 1000));
----------------立即执行-----------------------
所以对于字节防抖与节流面试问的可以很深
可见:apply, arguments
函数柯里化