防抖节流原理区别以及js实现

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

防抖(debounce)

原理:在被触发n秒之后在执行回调,如果在这n秒内又被触发,则重新计时

应用场景:

  1. 按钮提交场景:防止多次提交按钮,只执行最后一次

  2. 搜索框联想场景:防止联想发送请求,只发送最后一次输入

解决方案:

简易版

在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后:

  • 如果在200ms内没有再次触发滚动事件,那么就执行函数
  • 如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时
function debounce(func,wait){
	let timeout;
	return function(){
		const context = this;
		const args = arguments;
		clearTimeOut(timeout);
		timeout = setTimeout(() => {
			func.apply(context,args);
		}, wait);
	}
}
复制代码

立即执行版

有时候希望立即执行,然后等到停止触发数秒后,才可以重新执行

function debounce(func,wait,immediate){
    let timeout;
    return function(){
        const context = this;
        const args = arguments;
        // 有触发重新计时
        if(timeout) ClearTimeout(timeout);
        if(immediate){
            const callNow = !timeout;
            timeout = setTimeout(() => {
                timeout = null;
            }, wait);
            // timeout = null 时 执行函数
            if(callNow) func.apply(context.args);
        }else{
            timeout = setTimeout(() => {
                func.apply(context,args);
            }, wait)
        }

    }
}
复制代码

节流(throttle)

如果用户咋wait时间内不停的触发事件,那么就可能一直不能执行,如果需要一段时间内生效一次,就需要用到节流。

原理:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

适用场景:

  1. 拖拽场景:固定时间内只执行一次,防止高频次触发位置变动。

  2. 缩放场景: 监控浏览器resize

解决方案:

使用时间戳

当触发事件发生的时候,我们取出当前时间戳,然后减去之前的时间戳(最开始设值为0),如果大于设置的时间周期,就执行函数,然后更新时间戳为当前时间戳,如果小于就跳过

function throttle(fnc,delay){
    let context, args;
    let previous = new Date();
    return function(){
        let now = new Date();
        context = this;
        args = arguments;
        if(now - previous > delay){
            func.apply(context,args);
            previous = now;
        }
    }
}
复制代码

使用定时器

当触发事件的时候,我们设置一个定时器,在触发事件的时候如果定时器存在,就不执行,直到定时器执行,然后清空执行函数,清空定时器,在设置下一个定时器

function throttle(fnc,delay){
    let timeout;
    return function(){
        let context = this;
        let args = arguments;
        if(timeout){
            timeout = setTimeout(()=>{
                timeout = null;
                func.apply(context,args);
            },delay);
          
        }
    }
}
复制代码

区别:节流不管事件触发多频繁保证在一定时间内一定会执行一次桉树,当都是自在最后一次时间后才会执行一次函数。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享