You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 有时希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。functiondebounce(func,wait,immediate){lettimeout;returnfunction(){constcontext=this;constargs=arguments;if(timeout)clearTimeout(timeout);if(immediate){constcallNow=!timeout;timeout=setTimeout(function(){timeout=null;},wait)if(callNow)func.apply(context,args)}else{timeout=setTimeout(function(){func.apply(context,args)},wait);}}}
防抖:在n秒时间内,不停的被触发,只执行最后一次 function debounce(fn, n){
let timer = null
return function (){
if(timer) {
clearTimeout(timer)
timer = setTimeout(fn, n)
} else {
timer = setTimeout(fn, n)
}
}
}
节流:在n秒时间内,不停的被触发,只执行第一次 function throttre (fn, n){
let flag = true
return function(){
if(!flag) return
flag = false
setTimeout(()=>{
fn()
flag = true
},n)
}
}
//防抖
function debounce(fn,n){
let timer =null;
return function(){
clearTimeout(timer);
timer= setTimeout(fn,n);
}
}
let con=debounce(()=>console.log('1'),2000);
最后,假设有一个搜索框,通过getElementById获取其 DOM 元素,并监听它的input事件。在事件处理函数中,使用防抖版本的搜索函数debouncedSearch来处理用户输入的查询内容。这样,即使用户在输入框中快速输入,也不会立即触发搜索操作,而是会等待用户停止输入一段时间后再执行搜索。
functionupadateScrollPosition(){console.log("Scroll position updated:",window.scrollY);}constthrottledUpdateScrollPosition=throttle(upadateScrollPosition,300);window.addEventListener("scroll",throttledUpdateScrollPosition);
Activity
Genzhen commentedon Jun 23, 2020
1)防抖
2)节流
Genzhen commentedon Jun 23, 2020
区别:节流不管事件触发多频繁保证在一定时间内一定会执行一次函数。防抖是只在最后一次事件触发后才会执行一次函数
123456zzz commentedon Jul 13, 2020
yaooooooooo commentedon Jul 20, 2020
const createProxyThrottle = (fn,rate){
const lastClick = Date.now() - rate;
return new Proxy(fn,{
apply(target,context,args){
if(Date.now() - lastClick >= rate){
fn(args);
lastClick = Date.now();
}
}
})
}
GolderBrother commentedon Jul 20, 2020
// 1. 防抖:不停的触发事件,只执行最后一次
// 指的是某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。假如我们设置了一个等待时间 3 秒的函数,在这 3 秒内如果遇到函数调用请求就重新计时 3 秒,直至新的 3 秒内没有函数调用请求,此时执行函数,不然就以此类推重新计时。
function debounce(fn, wait = 500, immediate = false) {
let timer = null,
result = null;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
if (immediate && !timer) {
result = fn.apply(this, args);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, wait);
return result;
}
}
// 2. 函数节流指的是某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内 无视后来产生的函数调用请求,也不会延长时间间隔。3 秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的 3 秒内依旧无视后来产生的函数调用请求,以此类推。
// 函数节流非常适用于函数被频繁调用的场景,例如:window.onresize() 事件、mousemove 事件、上传进度等情况。
function throttle(fn, wait = 500, immediate = false) {
let timer = null, startTime = Date.now(), result = null;
return function (...args) {
if(immediate) result = fn.apply(this, args);
const now = Date.now();
// 超过了延时时间,马上执行
if(now - startTime > wait) {
// 更新开始时间
startTime = Date.now();
result = fn.apply(this, args);
}else {
// 否则定时指定时间后执行
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
// 更新开始时间
startTime = Date.now();
fn.apply(this, args);
}, wait);
}
}
}
niunaibinggan commentedon Aug 31, 2020
防抖:在n秒时间内,不停的被触发,只执行最后一次
function debounce(fn, n){
let timer = null
return function (){
if(timer) {
clearTimeout(timer)
timer = setTimeout(fn, n)
} else {
timer = setTimeout(fn, n)
}
}
}
节流:在n秒时间内,不停的被触发,只执行第一次
function throttre (fn, n){
let flag = true
return function(){
if(!flag) return
flag = false
setTimeout(()=>{
fn()
flag = true
},n)
}
}
tintinng commentedon Oct 21, 2020
为什么防抖的返回值版本不能直接在函数的调用中直接反返回呢?
return func.apply(context, args);
这样不是在不立即执行的时候也可以返回值了嘛
chengazhen commentedon Nov 4, 2020
Bilibiber commentedon Dec 3, 2020
const Throttling = (fn, delay) =>{
let last = 0;
return function(){
const now = new Date().getTime();
console.log(now-last);
if(now-last<delay) return;
last = now;
return fn();
}
}
JiaLe1 commentedon May 17, 2021
yingyingying-zhou commentedon May 26, 2021
对
PassionPenguin commentedon Jun 8, 2021
Luoyuda commentedon Jun 9, 2021
zizxzy commentedon Nov 1, 2021
chihaoduodongxi commentedon Feb 18, 2022
//防抖
function debounce(fn,n){
let timer =null;
return function(){
clearTimeout(timer);
timer= setTimeout(fn,n);
}
}
let con=debounce(()=>console.log('1'),2000);
chihaoduodongxi commentedon Feb 18, 2022
//节流
function throttle(fn, n) {
let flag = true;
return function () {
if (flag) {
fn();
flag = false;
setTimeout(() => (flag = true), n); }
};
}
Kisthanny commentedon Mar 20, 2024
TANGYC-CS commentedon Apr 9, 2024
防抖(debounce)和节流(throttle)是两种常用的性能优化手段,尤其在处理高频触发的事件(如滚动、窗口大小调整、键盘输入等)时非常有用。
防抖(Debounce)
如果一个函数持续被触发,那么在这个函数执行一次之后,只有在一定的时间间隔内没有再次被触发,才会执行第二次。
也就是说,防抖会确保函数在一定时间内只执行一次,即使在这段时间内被触发了很多次。
节流(Throttle)
在单位时间,无论触发多少次,函数都只会执行一次。
也就是说,节流会限制函数的执行频率,确保在单位时间内只执行一次。
区别
节流是不管事件触发多么频繁,都会保证在 n 秒内只执行一次。
应用
防抖的主要思想是:在一定时间内,事件处理函数只执行一次,如果在这个时间段内又触发了该事件,则重新计算执行时间。这适用于短时间内的大量触发场景,例如用户连续输入搜索关键字时,浏览器不会立即执行搜索请求,而是等待用户停止输入一段时间后,再执行搜索操作。这样可以避免在用户连续操作时发送过多的无意义请求,提高页面性能和用户体验。
而节流的主要思想是:在一段时间内最多触发一次事件,无论这个事件被触发了多少次。每次事件触发时,如果之前的事件还在等待执行,就取消之前的等待,并重新设置等待时间。节流适用于持续的触发场景,确保在一定时间间隔内至少执行一次操作,如监听滚动事件时,每隔一段时间更新页面位置等。
总结来说,防抖是将多次执行变为最后一次执行,而节流是将多次执行变成每隔一段时间执行。两者都可以有效减少事件触发的频率,但在不同的使用场景下,选择哪种方法取决于具体需求。如果需要确保用户停止操作一段时间后才执行,可以选择防抖;如果需要确保在一定时间内至少执行一次操作,可以选择节流。
防抖实现
这个防抖函数的工作原理是:
timeout
是否存在)。wait
毫秒内多次调用后执行func
。wait
毫秒后执行func
。wait
毫秒内再次调用这个返回的函数,它会再次清除定时器并设置一个新的,确保func
不会在这段时间内执行。wait
毫秒的等待期内没有再次调用这个返回的函数时,func
才会最终被执行。这种机制非常适用于处理如输入框实时搜索、窗口大小调整等需要延迟执行的任务,因为这样可以防止函数在短时间内被频繁调用,从而提高性能。
如何使用防抖
要使用上面的防抖函数,需要首先定义一个需要防抖处理的函数,然后将其传递给
debounce
函数来获取一个新的防抖函数。之后,你可以像调用普通函数一样调用这个新的防抖函数。具体使用示例:
在上面的代码中,首先定义了一个防抖函数
debounce
,它接受一个需要防抖的函数func
和一个等待时间wait
作为参数。防抖函数返回一个新的函数,这个新函数会在每次调用时取消之前的等待定时器,并重新设置一个新的等待定时器。只有在等待时间过后,才会执行原函数
func
。接下来,定义了一个实时搜索函数
search
,它接受一个查询参数query
,并打印出搜索内容。在实际应用中,这个函数可能会发送搜索请求到服务器。然后,使用
debounce
函数创建了一个防抖版本的搜索函数debouncedSearch
,并设置防抖间隔为 500 毫秒。这意味着在用户停止输入 500 毫秒后,才会执行搜索操作。最后,假设有一个搜索框,通过
getElementById
获取其 DOM 元素,并监听它的input
事件。在事件处理函数中,使用防抖版本的搜索函数debouncedSearch
来处理用户输入的查询内容。这样,即使用户在输入框中快速输入,也不会立即触发搜索操作,而是会等待用户停止输入一段时间后再执行搜索。这种方式可以有效减少不必要的搜索请求,提高性能和用户体验。
节流实现
throttle
函数接受一个需要被节流的函数func
和一个时间间隔limit
作为参数。它返回一个内部函数,这个内部函数在每次调用时都会检查是否处于节流状态。
如果不处于节流状态,它会调用
func
函数,并将节流状态设置为true
,然后设置一个定时器在limit
毫秒后将节流状态重置为false
。如果处于节流状态,则不会执行
func
函数。通过这种方式,可以确保
func
函数在指定的时间间隔内只被调用一次。如何使用节流
滚动事件监听: 当页面滚动时,可能希望执行某些操作,比如懒加载图片、更新导航栏状态等。
但是,如果每次滚动都触发这些操作,会导致性能问题。
使用节流函数可以确保在一定时间间隔内只执行一次操作。