一个例子学习防抖、节流

防抖、节流函数主要是用来限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟、假死或卡顿的现象的。

比如我在项目中遇到过输入查询的功能,在搜索框中输入文字调用查询接口搜索,返回与搜索框匹配的内容。

先来一个基础的写法:
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
    <input type="text" class="search" placeholder="搜索...">
    <script type="text/javascript">
        $("body").on("keyup", ".search", function() {  //输入时调用searchFunc函数
            searchFunc();
        })
    	var searchFunc = function() {
    	    console.log('请求接口返回搜索内容。。。');
    	}
    </script>
</body>
</html>
复制代码

这是这个搜索功能实现的雏形,但是运行起来会发现,只要我不断的输入,它就会不断地调用searchFunc 方法去请求接口,就是说我输入10次就会请求10次。这想想真是很糟糕透了,怎么优化这个问题呢?

接下来就要用到防抖思想了。

防抖函数代码实现

(用本例解释)防抖其实就是加上一个定时器,规定它延迟一定的时间再去请求接口。

<!DOCTYPE html>
<html>
<head>
    <title>防抖实现搜索</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
    <input type="text" class="search" placeholder="搜索...">
    <script type="text/javascript">
        $("body").on("keyup", ".search", function() {
            searchFunc();
	    })
	var timer = null;
	var searchFunc = function() {
	    timer && clearTimeout(timer);
	    timer = setTimeout(function() {
	        console.log('请求接口返回搜索内容。。。');
	    }, 5000);
	}
    </script>
</body>
</html>
复制代码

加上了定时器之后,再运行看看,它不会再是输入多少次就请求多少次了。

而是延时5秒之后再去做一次请求。

需要注意的是:在这个5秒钟的时间里,你不断的输入,定时器会不断的被清除再重新设置一个。举个例子:你第一秒的时候第一次输入内容,那它开始设置一个定时器并且延时5秒钟,等到第四秒钟的时候你再次输入内容,此时程序是先把你之前设置的定时器先清除再给你重新设置一个新的定时器,这个定时器又延时5秒钟。也就是说这个定时器以你这5秒钟时间内最后一次输入的为准。

这样就解决了频繁请求的问题。

另外,我们还可以使用函数节流来优化这个问题。

节流函数代码实现

(用本例解释)给定一个间隔时间,计算一个等待时间,当等待时间大于间隔时间,则再去请求接口

<!DOCTYPE html>
<html>
<head>
    <title>节流实现搜索</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
    <input type="text" class="search" placeholder="搜索...">
    <script type="text/javascript">
        $("body").on("keyup", ".search", function() {
            searchFunc(5000);
        })
        var lastTime = null, nowTime = null;
        var searchFunc = function(gapTime) {
            nowTime = new Date().getTime();
            if(nowTime - lastTime > gapTime || !lastTime) {
                console.log('请求接口返回搜索内容。。。');
                lastTime = nowTime;
            }
        }
    </script>
</body>
</html>
复制代码

从代码可以看出来就是比较当前时间和 lastTime 的差值,当差值大于gapTime的时候就去调用接口。

函数节流的思想在本例来的体现:就是给定一个时间gapTime(比如5秒钟)代表每隔5秒钟请求一次接口搜索。不管你怎么输入,我都是按部就班的每隔5秒钟请求一次。

至于什么时候用防抖什么时候用节流,还得具体问题具体分析。

转载于:https://juejin.im/post/5c19e2e3f265da612e289585

<< ### 手写Promise **实现思路:** - Promise有三种状态:`pending(进行中)`, `fulfilled/resolved(已成功完成)`, `rejected(失败/拒绝)。` - 只能从“未完成”转变为其他两种状态,并且回调函数应该异步执行。 ```javascript class MyPromise { constructor(executor) { this.state = 'pending'; // 初始为 pending 状态 this.value = undefined; this.reason = undefined; let resolve = (value) => { if(this.state === "pending") { this.value = value; this.state = "fulfilled"; } }; let reject = (reason) => { if(this.state === "pending") { this.reason = reason; this.state = "rejected"; } }; try{ executor(resolve, reject); } catch(e){ reject(e); } } then(onFulfilled, onRejected) { switch(this.state) { case "fulfilled": onFulfilled && onFulfilled(this.value); break; case "rejected": onRejected && onRejected(this.reason); break; default: console.log("the promise is still pending"); } } } ``` 这段代码展示了最基础的自定义`MyPromise`构造器以及它的核心逻辑。然而,在实际使用时还需要支持链式调用、处理thenable对象等复杂情况,因此这只是一个简单的模拟版本。 --- ### 防抖 Debounce 防抖原理是在一定时间内如果再次触发事件,则重新计时;若超过设定的时间没有再触发该事件则执行回调函数。 这种机制适用于如窗口调整大小、输入框内容变化等情况下的性能优化。 #### 实现方式: ```js function debounce(fn, delay) { let timerId; return function(...args) { const context = this; clearTimeout(timerId); timerId = setTimeout(() => fn.apply(context, args), delay); }; } // 使用示例: window.onresize = debounce(function() { console.log('Window resized'); }, 500); ``` 在这个例子中我们创建了一个名为`debounce()`的新功能接受两个参数 - 我们要延迟执行的功能(`fn`) 和 延迟时间 (`delay`). 当被绑定到某个DOM元素上作为监听器的时候,它会在最后一次触发后的指定毫秒数后才去真正地调用原函数. --- ### 节流 Throttle 与防抖不同的是,节流是指在一个时间段内只允许执行一次操作,即使在此期间多次触发也只会响应第一次或最后一次请求。常用于控制频繁发生的任务频率限制,比如滚动页面加载更多数据等功能。 #### 实现方式: ```js function throttle(func, limit) { let inThrottle; return (...args) => { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => (inThrottle = false), limit); } }; } // 示例用途如下所示: const throttledScrollHandler = throttle((event) => { console.log(event.target.scrollTop); }, 500); document.addEventListener('scroll', throttledScrollHandler); ``` 这里实现了`throttle()`方法来帮助减少过于密集的操作次数并提高用户体验流畅度。每当用户停止活动超过给定的时间段之后才会继续接收新消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值