jwplayer onTime() calling setInterval() several times per second - javascript

My main goal is at 7:45 in the video to display a countdown timer from 20:00.
Here is my event called by the jwplayer I'm using:
onTime: function(event){showTimer(event.position);}
Here is my funciton showTimer:
function showTimer(video_position){
// Schedule the update to happen once every second
if(Math.round(video_position) == 465){
setInterval(updateTimer, 1000);
}
};
The Problem:
Because it onTime() isn't guaranteed to hit right at 465.0 I have to d a Math.round on the video position. If I do this, 4-10 onTime event handlers knock off within 465.0 - 466.0 so my setInterval() gets called several times and the timer counts down insanely fast.
Is there a way to make it hit the setInterval() once or maybe a global variable I can set the first time to let setInterval() know its already been knocked off?

I'd just use a boolean flag to check whether the event has fired yet.
var fired = false;
if(Math.round(video_position) == 465 && !fired){
fired = true;
setInterval(updateTimer, 1000);
}
That way it can only fire the event once.

Related

The debounce method from underscore library isn't working as expected, how do I create a function that can only be called once a second? [duplicate]

Can anyone give me a in-simple-words explanation about the difference between throttling and debouncing a function for rate-limiting purposes.
To me both seems to do the same the thing. I have checked these two blogs to find out :
http://remysharp.com/2010/07/21/throttling-function-calls
http://benalman.com/projects/jquery-throttle-debounce-plugin/
To put it in simple terms:
Throttling will delay executing a function. It will reduce the notifications of an event that fires multiple times.
Debouncing will bunch a series of sequential calls to a function into a single call to that function. It ensures that one notification is made for an event that fires multiple times.
You can visually see the difference here
If you have a function that gets called a lot - for example when a resize or mouse move event occurs, it can be called a lot of times. If you don't want this behaviour, you can Throttle it so that the function is called at regular intervals. Debouncing will mean it is called at the end (or start) of a bunch of events.
Personally I found debounce harder to comprehend than throttle.
As both functions help you postpone and reduce the rate of some execution. Assuming you are calling decorated functions returned by throttle/debounce repeatedly...
Throttle: the original function will be called at most once per specified period.
Debounce: the original function will be called after the caller stops calling the decorated function after a specified period.
I found the last part of debounce crucial to understand the goal it's trying to achieve. I also found an old version of the implementation of _.debounce helps the understanding (courtesy of https://davidwalsh.name/function-debounce).
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
A far-fetched metaphor, but maybe could also help.
You have a friend named Chatty who likes to talk with you via IM. Assuming when she talks she sends a new message every 5 seconds, while your IM application icon is bouncing up and down, you can take the...
Naive approach: check every message as long as it arrives. When your app icon bounces, check. It's not the most effective way, but you are always up-to-date.
Throttle approach: you check once every 5 minutes (when there are new ones). When new message arrives, if you have checked anytime in the last 5 minutes, ignore it. You save your time with this approach, while still in the loop.
Debounce approach: you know Chatty, she breaks down a whole story into pieces, sends them in one message after another. You wait until Chatty finishes the whole story: if she stops sending messages for 5 minutes, you would assume she has finished, now you check all.
Differences
+--------------+-------------------+-------------------+
| | Throttle 1 sec | Debounce 1 sec |
+--------------+-------------------+-------------------+
| Delay | no delay | 1 sec delay |
| | | |
| Emits new if | last was emitted | there is no input |
| | before 1 sec | in last 1 sec |
+--------------+-------------------+-------------------+
Explanation by use case:
Search bar- Don't want to search every time user presses key? Want to search when user stopped typing for 1 sec. Use debounce 1
sec on key press.
Shooting game- Pistol take 1 sec time between each shot but user click mouse multiple times. Use throttle on mouse click.
Reversing their roles:
Throttling 1 sec on search bar- If users types abcdefghij with every character in 0.6 sec. Then throttle will trigger at first a press. It will will ignore every press for next 1 sec i.e. bat .6 sec will be ignored. Then c at 1.2 sec will again trigger, which resets the time again. So d will be ignored and e will get triggered.
Debouncing pistol for 1 sec- When user sees an enemy, he clicks mouse, but it will not shoot. He will click again several times in that sec but it will not shoot. He will see if it still has bullets, at that time (1 sec after last click) pistol will fire automatically.
Further explanation for input-output comparision with real life
There are some guards outside a bar. Guard allows person who say "I will go" to let inside the bar. That is a normal scenario. Anyone saying "I will go" is allowed to go inside the bar.
Now there is a Throttle Guard (throttle 5 sec). He likes people who responds first. Anyone who says "I will go" first, he allows that person. Then he rejects every person for 5 sec. After that, again anyone saying it first will be allowed and others will be rejected for 5 sec.
There is another Debounce Guard (debounce 5 sec). He likes people who brings mental rest to him for 5 seconds. So if any person says "I will go", the guard wait for 5 seconds. If no other person disturbs him for 5 seconds, he allow the first person. If some other person says "I will go" in those 5 sec, he reject the first one. He again starts the 5 sec waiting for the second person to see if the second one can bring him the mental rest.
Throttle (1 sec): Hello, I am a robot. As long as you keep pinging me, I will keep talking to you, but after exactly 1 second each. If you ping me for a reply before a second is elapsed, I will still reply to you at exactly 1 second interval. In other words, I just love to reply at exact intervals.
Debounce (1 sec): Hi, I am that ^^ robot's cousin. As long as you keep pinging me, I am going to remain silent because I like to reply only after 1 second is passed since the last time you pinged me. I don't know, if it is because I have an attitude problem or because I just don't like to interrupt people. In other words, if you keep asking me for replies before 1 second is elapsed since your last invocation, you will never get a reply. Yeah yeah...go ahead! call me rude.
Throttle (10 min): I am a logging machine. I send system logs to our backend server, after a regular interval of 10 minutes.
Debounce (10 sec): Hi, I am not cousin of that logging machine. (Not every debouncer is related to a throttler in this imaginary world). I work as a waiter in a nearby restaurant. I should let you know that as long as you keep adding stuff to your order, I will not go to the kitchen for execution of your order. Only when 10 seconds have elapsed after you last modified your order, I will assume that you are done with your order. Only then will I go and execute your order in the kitchen.
Cool Demos: https://css-tricks.com/debouncing-throttling-explained-examples/
Credits for the waiter analogy: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf
Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."
Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
ref
In layman's terms:
Debouncing will prevent a function from running while it is still being called frequently. A debounced function will only run after it has been determined that it is no longer being called, at which point it will run exactly once. Practical examples of debouncing:
Auto-saving or validating the contents of a text-field if the user "stopped typing": the operation will only be done once, AFTER it has been determined that the user is no longer typing (no longer pressing keys).
Logging where users rest their mouse: the user is no longer moving their mouse, so the (last) position can be logged.
Throttling will simply prevent a function from running if it has run recently, regardless of the call frequency. Practical examples of throttling:
Implementations of v-sync are based on throttling: the screen will only be drawn if 16ms elapsed since the last screen draw. No matter how many times the screen refresh functionality is called, it will only run at most once every 16ms.
It's simpler than the demos.
They do the exact same thing (rate limiting) but while throttle is being called it fires your function periodically, while debounce just fires once at the end.
Throttle fires throughout, debounce only fires at the end.
Example: If you're scrolling, throttle will slowly call your function while you scroll (every X milliseconds). Debounce will wait until after you're done scrolling to call your function.
--
I like to think of throttle as "including debounce", they both make a final call after the events are done, but due to implementation details, the two don't always make this final call at the exact same time, which can make demos confusing.
A real-life analogy that personally helps me remember:
debounce = a conversation. you wait for the other person to finish speaking before you reply.
throttle = a drum bit. you only play notes on a simple 4/4 drum bit.
Use cases for debounce:
Typing. You want to do something after the user stopped typing. So waiting 1sec after the last keystroke makes sense. Each keystroke restarts the wait.
Animation. You want to shrink back an element after the user stopped hovering over it. Not using debounce might cause an erratic animation as a result of the cursor unintentionally moving between the "hot" and "cold" zones.
Use cases for throttle:
Scrolling. You want to react to scrolling but limit the amount of calculations made, so doing something every 100ms is enough to prevent potential lag.
Mouse move. Same as scrolling but for mouse move.
API calls You want to fire an API call on certain UI events but want to limit the number of API calls you make not to overload your server.
Debouncing allows you to manage the frequency of calls that a function can receives. It combines multiple calls that happen on a given function so that repeated calls that occur before the expiration of a specific time duration are ignored. Basically debouncing ensures that exactly one signal is sent for an event that may be happening several times.
Throttling restricts the frequency of calls that a function receives to a fixed time interval. It is used to ensuring that the target function is not invoked more often than the specified delay. Throttling is the reduction in rate of a repeating event.
A picture is worth a thousand words
Throttle
Debounce
Notice the Debounce will not fire until the events flow stops. However, Throttle will fire an event each interval.
(Thanks to css-tricks)
Throttling
Throttling enforces a maximum number of times a function can be called
overtime. As in "execute this function at most once every 100
milliseconds." Say under normal circumstances you would call this
function 1,000 times over 10 seconds. If you throttle it to only once
per 100 milliseconds, it would only execute that function at most 100
times
(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls
Debouncing
Debouncing enforces that a function not be called again until a
certain amount of time has passed without it being called. As in
"execute this function only if 100 milliseconds have passed without it
being called."
Perhaps a function is called 1,000 times in a quick burst, dispersed over 3 seconds, then stops being called. If you have debounced it at 100 milliseconds, the function will only fire once, at 3.1 seconds, once the burst is over. Each time the function is called during the burst it resets the debouncing timer
source:- throttle and debouncing
Putting debounce and throttle together can be very confusing, because they both share a parameter called delay.
Debounce. The delay is to wait till there's no more invokes anymore, then to invoke it. Very much like to close an elevator door: the door has to wait till no one tries to get in before closing.
Throttle. The delay is to wait with a frequency, then invokes for the last one. Very much like to fire a pistol gun, the gun just can't be fired beyond certain rate.
Let's take a look at the implementation to see in details.
function debounce(fn, delay) {
let handle = null
return function () {
if (handle) {
handle = clearTimeout(handle)
}
handle = setTimeout(() => {
fn(...arguments)
}, delay)
}
}
Debounce, keeps interrupting the timeout until no more interruptions, and then fires fn.
function throttle(fn, delay) {
let handle = null
let prevArgs = undefined
return function() {
prevArgs = arguments
if (!handle) {
fn(...prevArgs)
prevArgs = null
handle = setInterval(() => {
if (!prevArgs) {
handle = clearInterval(handle)
} else {
fn(...prevArgs)
prevArgs = null
}
}, delay)
}
}
}
Throttle, stores the last call arguments, and sets up an interval to fire until no past fires any more.
Similarities. They both have a delay time, and there's no fire during the delay, especially when there's only one fire. Both do not aggregate past events, so the number of events can be different than the actual fires.
Difference. The delay can be extended in debounce case with repeated events. Whereas the delay in the throttle case is fixed. So in general you get more fires from the throttle than debounce.
Easy to remember. Debounce groups bundle calls into one. Throttle keeps bundle calls within certain frequency.
Updated 1-20-23
Throttle might not need setInterval, here's a new version I wrote recently which takes care of this as well.
function throttle(fn, delay) {
let canFire = true
let queue = []
function pop() {
if (queue.length < 1) return
const [that, args] = queue.pop()
fn.apply(that, args)
canFire = false
setTimeout(() => {
canFire = true
pop()
}, delay)
}
function push() {
queue.push([this, arguments])
if (canFire) pop()
}
push.cancel = () => {
queue = []
}
return push
}
throtle is just a wrapper around debounce which makes debounce to call passed function in some period of time, if debounce delays a function call on period of time which is bigger then specified in throtle.
Suppose we have a callback function "cb" to be called on event "E".
Let "E" getting triggered 1000 times in 1 second, hence there would be 1000 calls to "cb". That is 1 call/ms. To optimize we can either use:
Throttling: With throttling of (100ms), "cb" would be
called on [100th ms, 200th ms, 300th ms, ... 1000th ms]. That is 1 call/100 ms. Here 1000 calls to "cb" optimized to 10 calls.
Debouncing: With debouncing of (100ms), "cb" would be called only once on [1100th sec]. That is 100ms after the last trigger of "E" which happend on [1000th ms]. Here 1000 calls to "cb" optimized to 1 call.
the lodash Library suggests the following article https://css-tricks.com/debouncing-throttling-explained-examples/ which detailed explain the difference between Debounce and Throttle and their origination
Debouncing and Throttling are ways to select targets from a serial of events for the purpose of reduction. Both of they need a period of time as an argument, for example: x ms, and trailing / leading variety to define how to select.
Debouncing
Select an event when no other event occurs in next x ms
"--->": timeline "o,e": events "|===|": period (x=5)
--oo-e-----ooo-e----o-oo--oe-----o-o-ooe------> events
|===| |===| |===| |===|
||===| ||===| | |===| | |===|
| |===| | |===| | |===| | |===|
| | | |===|| |===| | |===|
| | | || |===| | |===|
---------e---------e-----------e-----------e--> selected events (trailing)
--o--------o--------o------------o------------> selected events (leading)
Throttling
Select an event in every x ms when an event occurs
"--->": timeline "o,e": events "|===|": period (x=5)
--oo-e-----ooo-e----o-oe--oe-----o-o-eoe------> events
|===| |===| |===| |===| |===||===|
------e--------e--------e-----e------e----e---> selected events (trailing)
--o--------o--------o-----o------o----o-------> selected events (leading)
Debouncing makes it so a function can only be executed after a certain amount of time since it was last invoked
function debounce(func,wait){
let timeout
return(...arg) =>{
clearTimeout(timeout);
timeout= setTimeout(()=>func.apply(this,arg),wait)
}
}
function SayHello(){
console.log("Jesus is saying hello!!")
}
let x = debounce(SayHello,3000)
x()
The throttle pattern limits the maximum number of times a given event handler can be called over time. It lets the handler be called periodically, at specified intervals, ignoring every call that occurs before this wait period is over.
function throttle(callback, interval) {
let enableCall = true;
return (...args)=> {
if (!enableCall) return;
enableCall = false;
callback.apply(this, args);
setTimeout(() => enableCall = true, interval);
}
}
function helloFromThrottle(){
console.log("Jesus is saying hi!!!")
}
const foo = throttle(helloFromThrottle,5000)
foo()
As far as I understand, in simple terms
Throttling - similar to calling setInterval(callback) for certain number of times i.e calling same function for certain number of times over time on occurrence of event
and..
Debouncing - similar to calling setTImeout(callbackForApi) or calling a function after certain time has passed on occurrence of event.
This link can be helpful-
https://css-tricks.com/the-difference-between-throttling-and-debouncing/
For examples of typical uses cases, I recommend #Guy's answer. But the best way for me to understand these two concepts was to make it about pizzas. 🍕
Let's say you're an amazing pizza-maker, and so customers are in your shop constantly demanding more pizzas.
Throttling:
You decide you will only put out one pizza at the end of every hour, as long you received at least one request for pizza during that hour.
You receive 100 requests for pizzas in one hour, so you provide a pizza at the end of that hour. Then, you get no requests for pizza the next hour, so you don't put out a pizza. Then you get 10 requests for pizzas the next hour, and so you put out a pizza at the end of that hour.
Debouncing:
You are getting annoyed about your customers constantly demanding pizzas, and so you decide you will only give them a pizza after they have stopped asking you for a full minute.
They demand pizzas for 30 minutes straight, but then they stop asking for a minute after that. At that point, you will give them one pizza.
Then they demand pizzas for 5 minutes straight, and stop asking for a minute after that. At that point, you give them another pizza.
it’s in fact the way of limiting an event. For example, if you are listening on an event onclick, if it’s regular it will listen to every click you made.
If you use Throttle, it will set an interval between the time you want to listen to event for example listen to one click every second.
Debounce is a more restrictive one, it will only fire itself at the beginning or the ending of an event. For example, you are scrolling and you use Debounce, it will trigger only when you start and you finish to scroll.
Debounce:
Executes the function after the interval if function isn't being called within that interval.
Throttle:
Executes the function n times at fixed interval.
How debouncing works in hardware.
Debouncing is the process of removing noise from a digital signal. When a button is pressed, the signal bouncing around can cause the button to be registered as being pressed multiple times. Debouncing removes this noise so that the button is only registered as being pressed once. Picture a ruler being bounced on the edge of a desk, and imagine metal contacts inside a switch bouncing like this.
Better still, look at this diagram, showing the switch noise caused by bouncing.
We use resistors and capacitors of properly calculated ratings to smooth out the signal for n ms.
Explain how signal throttling works in hardware.
Signal throttling is the process of limiting the number of times a signal can be registered. This is often used to prevent a button from being registered as being pressed multiple times in a short period of time.
I prefer the term gating, but that's because I'm into electronic music production.
We open the gate at the end of each throttle period, and allow the signal to pass, and then close the gate again, for the next throttle period.
Explain how debouncing works in software.
Debouncing in software is often accomplished by using a timer. When the button is pressed, the timer is started. If the button is pressed again before the timer expires, the timer is reset. This ensures that the button can only be registered as being pressed once per debounce period.
In many implementations of debounce, we create a debounced version of the function which is embedded in a closure containing a timer (or gate). When the timer delay expires we set it it null again. The actual function only runs when the timer is null. Usually, this means when we first call the debounced function, it'll run once, then subsequent calls to it will be effectively cancelled until the delay time has elapsed.
In some implementations of debounce, while a stream of calls are fired and the timer hasn't expired, the timer will be restarted. Only calling the function after the bouncing has stopped. This is usually called a trailing debounce.
Explain how throttling works in software.
Throttling in software is often accomplished by using a counter. When the button is pressed, the counter is incremented. If the button is pressed again before the counter reaches a certain threshold, the counter is reset. This limits the number of times the button can be registered as being pressed in a given period of time. It's good to visualise this as a pulse or beat, which opens and closes a gate while calls are being sent to the throttle.
Rate limiting is another way to think of a throttle.
Why is this such a common cause of confusion?
In many many use cases a debounce or throttle will get you the results you want, especially if the software implementation you're using allows you to chain, trail, or lead your throttle / debounce.
Still, I hope all the answers here and this one have helped you understand more clearly.
They're very similar.
This article explains it rather well and has graphics too.
https://css-tricks.com/debouncing-throttling-explained-examples/
From the article (and with some clarifications):
The main difference between this (throttle) and debouncing is that throttle guarantees the execution of the function regularly, at least every X milliseconds.
Normally debounce calls the function at the end of a specified time and throttle calls when the first call to the throttled function is made. Sometimes debounce can take extra config that changes this to do the call at the beginning instead. Some implemenations of debounce can actually do what throttle does (see Lodash source code) when called with specific configs.
Simple concept for throttle is clicking the submit button frequently in a form, we need to use throttle. So the submit function is prevent from frequent clicks. It saves the same requests pass into the function.
And about debounce, write a simple code with input text tag for searching some data from the server. oninput, you use the debounce so it removes the previous requests and pass the last typed word to the server
const throttle = (callback, time = 0) => {
let throttle_req, count = 0;
return async function () {
var context = this, args = arguments;
if(throttle_req) return;
throttle_req = true;
if(time > 0)
{
callback.apply(context, args);
setTimeout(() => {
throttle_req = false;
}, time || 200)
}
else
{
let response = await callback.apply(context, args);
throttle_req = false;
return response;
}
}
}
const debounce = (callback, time = 0) => {
let debounce_req;
return function () {
var context = this, args = arguments;
clearTimeout(debounce_req)
debounce_req = setTimeout(() => {
debounce_req = null;
callback.apply(context, args);
}, time || 200)
}
}
How we call: Just wrap your function with throttle or debounce to check the difference
Throttle ex: same button click more than 1 time
var throttleFunct = throttle(function(num) {
console.log(num, "hello throttle")
}, 2000);
throttleFunct(300) //it execute. because its the first call
throttleFunct(400) //it won't execute
throttle async without time
var getDataAsync = throttle(function(id, name) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({name: name, id: id})
}, 2000)
})
});
async function test() {
let response = await getDataAsync(120, 'Sherley').then(resp => resp)
console.log(response, "respond") //it execute. because its the first call
response = await getDataAsync(120, 'James').then(resp => resp)
console.log(response, "respond2")//it executes 2 after first request
response = await getDataAsync(120, 'Jonathan').then(resp => resp)
console.log(response, "respond3")//it executes 3 after second request
}
test()
Debounce For ex: search box autocomplete
var debounceFunct = debounce(function(num) {
console.log(num+1)
}, 2000);
debounceFunct(300) //it won't execute and it cancelled
debounceFunct(400) // it executes and it replaced with the previous call. because this is the latest event fire
The major difference between debouncing and throttling is that debounce calls a function when a user hasn't carried out an event in a specific amount of time, while throttle calls a function at intervals of a specified amount of time while the user is carrying out an event.
What really matters here, in most simple terms: if you have some action, that is continuously repeated for some period (such as mouse movement, or page resize events), and you need to run some function in response, but you don't want to react to every action (cause it may detriment the performance), you have 2 options:
debounce - you skip all incoming actions, except the last one (the 'last one' is defined by the 'wait' time period you set for debounce function, for example, 2s - it will consider that actions flood stopped, if no actions were taken for 2s, and then it will react. This strategy is reasonable if you don't care about regular updates, you just need to react at least once.
throttle - if you want to react 'on schedule', to make regular updates even if actions flood is endless, you make your function run at regular intervals (no more often, then the specified time interval), for example 2s throttling will mean that your response will be executed an once if action is taken, but no less then 2s after that. So with continuous actions flood your response will be run on 0s, 2s, 4s, 6s, 8s...

Difference Between throttling and debouncing a function

Can anyone give me a in-simple-words explanation about the difference between throttling and debouncing a function for rate-limiting purposes.
To me both seems to do the same the thing. I have checked these two blogs to find out :
http://remysharp.com/2010/07/21/throttling-function-calls
http://benalman.com/projects/jquery-throttle-debounce-plugin/
To put it in simple terms:
Throttling will delay executing a function. It will reduce the notifications of an event that fires multiple times.
Debouncing will bunch a series of sequential calls to a function into a single call to that function. It ensures that one notification is made for an event that fires multiple times.
You can visually see the difference here
If you have a function that gets called a lot - for example when a resize or mouse move event occurs, it can be called a lot of times. If you don't want this behaviour, you can Throttle it so that the function is called at regular intervals. Debouncing will mean it is called at the end (or start) of a bunch of events.
Personally I found debounce harder to comprehend than throttle.
As both functions help you postpone and reduce the rate of some execution. Assuming you are calling decorated functions returned by throttle/debounce repeatedly...
Throttle: the original function will be called at most once per specified period.
Debounce: the original function will be called after the caller stops calling the decorated function after a specified period.
I found the last part of debounce crucial to understand the goal it's trying to achieve. I also found an old version of the implementation of _.debounce helps the understanding (courtesy of https://davidwalsh.name/function-debounce).
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
A far-fetched metaphor, but maybe could also help.
You have a friend named Chatty who likes to talk with you via IM. Assuming when she talks she sends a new message every 5 seconds, while your IM application icon is bouncing up and down, you can take the...
Naive approach: check every message as long as it arrives. When your app icon bounces, check. It's not the most effective way, but you are always up-to-date.
Throttle approach: you check once every 5 minutes (when there are new ones). When new message arrives, if you have checked anytime in the last 5 minutes, ignore it. You save your time with this approach, while still in the loop.
Debounce approach: you know Chatty, she breaks down a whole story into pieces, sends them in one message after another. You wait until Chatty finishes the whole story: if she stops sending messages for 5 minutes, you would assume she has finished, now you check all.
Differences
+--------------+-------------------+-------------------+
| | Throttle 1 sec | Debounce 1 sec |
+--------------+-------------------+-------------------+
| Delay | no delay | 1 sec delay |
| | | |
| Emits new if | last was emitted | there is no input |
| | before 1 sec | in last 1 sec |
+--------------+-------------------+-------------------+
Explanation by use case:
Search bar- Don't want to search every time user presses key? Want to search when user stopped typing for 1 sec. Use debounce 1
sec on key press.
Shooting game- Pistol take 1 sec time between each shot but user click mouse multiple times. Use throttle on mouse click.
Reversing their roles:
Throttling 1 sec on search bar- If users types abcdefghij with every character in 0.6 sec. Then throttle will trigger at first a press. It will will ignore every press for next 1 sec i.e. bat .6 sec will be ignored. Then c at 1.2 sec will again trigger, which resets the time again. So d will be ignored and e will get triggered.
Debouncing pistol for 1 sec- When user sees an enemy, he clicks mouse, but it will not shoot. He will click again several times in that sec but it will not shoot. He will see if it still has bullets, at that time (1 sec after last click) pistol will fire automatically.
Further explanation for input-output comparision with real life
There are some guards outside a bar. Guard allows person who say "I will go" to let inside the bar. That is a normal scenario. Anyone saying "I will go" is allowed to go inside the bar.
Now there is a Throttle Guard (throttle 5 sec). He likes people who responds first. Anyone who says "I will go" first, he allows that person. Then he rejects every person for 5 sec. After that, again anyone saying it first will be allowed and others will be rejected for 5 sec.
There is another Debounce Guard (debounce 5 sec). He likes people who brings mental rest to him for 5 seconds. So if any person says "I will go", the guard wait for 5 seconds. If no other person disturbs him for 5 seconds, he allow the first person. If some other person says "I will go" in those 5 sec, he reject the first one. He again starts the 5 sec waiting for the second person to see if the second one can bring him the mental rest.
Throttle (1 sec): Hello, I am a robot. As long as you keep pinging me, I will keep talking to you, but after exactly 1 second each. If you ping me for a reply before a second is elapsed, I will still reply to you at exactly 1 second interval. In other words, I just love to reply at exact intervals.
Debounce (1 sec): Hi, I am that ^^ robot's cousin. As long as you keep pinging me, I am going to remain silent because I like to reply only after 1 second is passed since the last time you pinged me. I don't know, if it is because I have an attitude problem or because I just don't like to interrupt people. In other words, if you keep asking me for replies before 1 second is elapsed since your last invocation, you will never get a reply. Yeah yeah...go ahead! call me rude.
Throttle (10 min): I am a logging machine. I send system logs to our backend server, after a regular interval of 10 minutes.
Debounce (10 sec): Hi, I am not cousin of that logging machine. (Not every debouncer is related to a throttler in this imaginary world). I work as a waiter in a nearby restaurant. I should let you know that as long as you keep adding stuff to your order, I will not go to the kitchen for execution of your order. Only when 10 seconds have elapsed after you last modified your order, I will assume that you are done with your order. Only then will I go and execute your order in the kitchen.
Cool Demos: https://css-tricks.com/debouncing-throttling-explained-examples/
Credits for the waiter analogy: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf
Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."
Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
ref
It's simpler than the demos.
They do the exact same thing (rate limiting) but while throttle is being called it fires your function periodically, while debounce just fires once at the end.
Throttle fires throughout, debounce only fires at the end.
Example: If you're scrolling, throttle will slowly call your function while you scroll (every X milliseconds). Debounce will wait until after you're done scrolling to call your function.
--
I like to think of throttle as "including debounce", they both make a final call after the events are done, but due to implementation details, the two don't always make this final call at the exact same time, which can make demos confusing.
In layman's terms:
Debouncing will prevent a function from running while it is still being called frequently. A debounced function will only run after it has been determined that it is no longer being called, at which point it will run exactly once. Practical examples of debouncing:
Auto-saving or validating the contents of a text-field if the user "stopped typing": the operation will only be done once, AFTER it has been determined that the user is no longer typing (no longer pressing keys).
Logging where users rest their mouse: the user is no longer moving their mouse, so the (last) position can be logged.
Throttling will simply prevent a function from running if it has run recently, regardless of the call frequency. Practical examples of throttling:
Implementations of v-sync are based on throttling: the screen will only be drawn if 16ms elapsed since the last screen draw. No matter how many times the screen refresh functionality is called, it will only run at most once every 16ms.
A real-life analogy that personally helps me remember:
debounce = a conversation. you wait for the other person to finish speaking before you reply.
throttle = a drum bit. you only play notes on a simple 4/4 drum bit.
Use cases for debounce:
Typing. You want to do something after the user stopped typing. So waiting 1sec after the last keystroke makes sense. Each keystroke restarts the wait.
Animation. You want to shrink back an element after the user stopped hovering over it. Not using debounce might cause an erratic animation as a result of the cursor unintentionally moving between the "hot" and "cold" zones.
Use cases for throttle:
Scrolling. You want to react to scrolling but limit the amount of calculations made, so doing something every 100ms is enough to prevent potential lag.
Mouse move. Same as scrolling but for mouse move.
API calls You want to fire an API call on certain UI events but want to limit the number of API calls you make not to overload your server.
Debouncing allows you to manage the frequency of calls that a function can receives. It combines multiple calls that happen on a given function so that repeated calls that occur before the expiration of a specific time duration are ignored. Basically debouncing ensures that exactly one signal is sent for an event that may be happening several times.
Throttling restricts the frequency of calls that a function receives to a fixed time interval. It is used to ensuring that the target function is not invoked more often than the specified delay. Throttling is the reduction in rate of a repeating event.
A picture is worth a thousand words
Throttle
Debounce
Notice the Debounce will not fire until the events flow stops. However, Throttle will fire an event each interval.
(Thanks to css-tricks)
Throttling
Throttling enforces a maximum number of times a function can be called
overtime. As in "execute this function at most once every 100
milliseconds." Say under normal circumstances you would call this
function 1,000 times over 10 seconds. If you throttle it to only once
per 100 milliseconds, it would only execute that function at most 100
times
(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls
Debouncing
Debouncing enforces that a function not be called again until a
certain amount of time has passed without it being called. As in
"execute this function only if 100 milliseconds have passed without it
being called."
Perhaps a function is called 1,000 times in a quick burst, dispersed over 3 seconds, then stops being called. If you have debounced it at 100 milliseconds, the function will only fire once, at 3.1 seconds, once the burst is over. Each time the function is called during the burst it resets the debouncing timer
source:- throttle and debouncing
Putting debounce and throttle together can be very confusing, because they both share a parameter called delay.
Debounce. The delay is to wait till there's no more invokes anymore, then to invoke it. Very much like to close an elevator door: the door has to wait till no one tries to get in before closing.
Throttle. The delay is to wait with a frequency, then invokes for the last one. Very much like to fire a pistol gun, the gun just can't be fired beyond certain rate.
Let's take a look at the implementation to see in details.
function debounce(fn, delay) {
let handle = null
return function () {
if (handle) {
handle = clearTimeout(handle)
}
handle = setTimeout(() => {
fn(...arguments)
}, delay)
}
}
Debounce, keeps interrupting the timeout until no more interruptions, and then fires fn.
function throttle(fn, delay) {
let handle = null
let prevArgs = undefined
return function() {
prevArgs = arguments
if (!handle) {
fn(...prevArgs)
prevArgs = null
handle = setInterval(() => {
if (!prevArgs) {
handle = clearInterval(handle)
} else {
fn(...prevArgs)
prevArgs = null
}
}, delay)
}
}
}
Throttle, stores the last call arguments, and sets up an interval to fire until no past fires any more.
Similarities. They both have a delay time, and there's no fire during the delay, especially when there's only one fire. Both do not aggregate past events, so the number of events can be different than the actual fires.
Difference. The delay can be extended in debounce case with repeated events. Whereas the delay in the throttle case is fixed. So in general you get more fires from the throttle than debounce.
Easy to remember. Debounce groups bundle calls into one. Throttle keeps bundle calls within certain frequency.
Updated 1-20-23
Throttle might not need setInterval, here's a new version I wrote recently which takes care of this as well.
function throttle(fn, delay) {
let canFire = true
let queue = []
function pop() {
if (queue.length < 1) return
const [that, args] = queue.pop()
fn.apply(that, args)
canFire = false
setTimeout(() => {
canFire = true
pop()
}, delay)
}
function push() {
queue.push([this, arguments])
if (canFire) pop()
}
push.cancel = () => {
queue = []
}
return push
}
throtle is just a wrapper around debounce which makes debounce to call passed function in some period of time, if debounce delays a function call on period of time which is bigger then specified in throtle.
Suppose we have a callback function "cb" to be called on event "E".
Let "E" getting triggered 1000 times in 1 second, hence there would be 1000 calls to "cb". That is 1 call/ms. To optimize we can either use:
Throttling: With throttling of (100ms), "cb" would be
called on [100th ms, 200th ms, 300th ms, ... 1000th ms]. That is 1 call/100 ms. Here 1000 calls to "cb" optimized to 10 calls.
Debouncing: With debouncing of (100ms), "cb" would be called only once on [1100th sec]. That is 100ms after the last trigger of "E" which happend on [1000th ms]. Here 1000 calls to "cb" optimized to 1 call.
the lodash Library suggests the following article https://css-tricks.com/debouncing-throttling-explained-examples/ which detailed explain the difference between Debounce and Throttle and their origination
Debouncing and Throttling are ways to select targets from a serial of events for the purpose of reduction. Both of they need a period of time as an argument, for example: x ms, and trailing / leading variety to define how to select.
Debouncing
Select an event when no other event occurs in next x ms
"--->": timeline "o,e": events "|===|": period (x=5)
--oo-e-----ooo-e----o-oo--oe-----o-o-ooe------> events
|===| |===| |===| |===|
||===| ||===| | |===| | |===|
| |===| | |===| | |===| | |===|
| | | |===|| |===| | |===|
| | | || |===| | |===|
---------e---------e-----------e-----------e--> selected events (trailing)
--o--------o--------o------------o------------> selected events (leading)
Throttling
Select an event in every x ms when an event occurs
"--->": timeline "o,e": events "|===|": period (x=5)
--oo-e-----ooo-e----o-oe--oe-----o-o-eoe------> events
|===| |===| |===| |===| |===||===|
------e--------e--------e-----e------e----e---> selected events (trailing)
--o--------o--------o-----o------o----o-------> selected events (leading)
Debouncing makes it so a function can only be executed after a certain amount of time since it was last invoked
function debounce(func,wait){
let timeout
return(...arg) =>{
clearTimeout(timeout);
timeout= setTimeout(()=>func.apply(this,arg),wait)
}
}
function SayHello(){
console.log("Jesus is saying hello!!")
}
let x = debounce(SayHello,3000)
x()
The throttle pattern limits the maximum number of times a given event handler can be called over time. It lets the handler be called periodically, at specified intervals, ignoring every call that occurs before this wait period is over.
function throttle(callback, interval) {
let enableCall = true;
return (...args)=> {
if (!enableCall) return;
enableCall = false;
callback.apply(this, args);
setTimeout(() => enableCall = true, interval);
}
}
function helloFromThrottle(){
console.log("Jesus is saying hi!!!")
}
const foo = throttle(helloFromThrottle,5000)
foo()
As far as I understand, in simple terms
Throttling - similar to calling setInterval(callback) for certain number of times i.e calling same function for certain number of times over time on occurrence of event
and..
Debouncing - similar to calling setTImeout(callbackForApi) or calling a function after certain time has passed on occurrence of event.
This link can be helpful-
https://css-tricks.com/the-difference-between-throttling-and-debouncing/
For examples of typical uses cases, I recommend #Guy's answer. But the best way for me to understand these two concepts was to make it about pizzas. 🍕
Let's say you're an amazing pizza-maker, and so customers are in your shop constantly demanding more pizzas.
Throttling:
You decide you will only put out one pizza at the end of every hour, as long you received at least one request for pizza during that hour.
You receive 100 requests for pizzas in one hour, so you provide a pizza at the end of that hour. Then, you get no requests for pizza the next hour, so you don't put out a pizza. Then you get 10 requests for pizzas the next hour, and so you put out a pizza at the end of that hour.
Debouncing:
You are getting annoyed about your customers constantly demanding pizzas, and so you decide you will only give them a pizza after they have stopped asking you for a full minute.
They demand pizzas for 30 minutes straight, but then they stop asking for a minute after that. At that point, you will give them one pizza.
Then they demand pizzas for 5 minutes straight, and stop asking for a minute after that. At that point, you give them another pizza.
it’s in fact the way of limiting an event. For example, if you are listening on an event onclick, if it’s regular it will listen to every click you made.
If you use Throttle, it will set an interval between the time you want to listen to event for example listen to one click every second.
Debounce is a more restrictive one, it will only fire itself at the beginning or the ending of an event. For example, you are scrolling and you use Debounce, it will trigger only when you start and you finish to scroll.
Debounce:
Executes the function after the interval if function isn't being called within that interval.
Throttle:
Executes the function n times at fixed interval.
How debouncing works in hardware.
Debouncing is the process of removing noise from a digital signal. When a button is pressed, the signal bouncing around can cause the button to be registered as being pressed multiple times. Debouncing removes this noise so that the button is only registered as being pressed once. Picture a ruler being bounced on the edge of a desk, and imagine metal contacts inside a switch bouncing like this.
Better still, look at this diagram, showing the switch noise caused by bouncing.
We use resistors and capacitors of properly calculated ratings to smooth out the signal for n ms.
Explain how signal throttling works in hardware.
Signal throttling is the process of limiting the number of times a signal can be registered. This is often used to prevent a button from being registered as being pressed multiple times in a short period of time.
I prefer the term gating, but that's because I'm into electronic music production.
We open the gate at the end of each throttle period, and allow the signal to pass, and then close the gate again, for the next throttle period.
Explain how debouncing works in software.
Debouncing in software is often accomplished by using a timer. When the button is pressed, the timer is started. If the button is pressed again before the timer expires, the timer is reset. This ensures that the button can only be registered as being pressed once per debounce period.
In many implementations of debounce, we create a debounced version of the function which is embedded in a closure containing a timer (or gate). When the timer delay expires we set it it null again. The actual function only runs when the timer is null. Usually, this means when we first call the debounced function, it'll run once, then subsequent calls to it will be effectively cancelled until the delay time has elapsed.
In some implementations of debounce, while a stream of calls are fired and the timer hasn't expired, the timer will be restarted. Only calling the function after the bouncing has stopped. This is usually called a trailing debounce.
Explain how throttling works in software.
Throttling in software is often accomplished by using a counter. When the button is pressed, the counter is incremented. If the button is pressed again before the counter reaches a certain threshold, the counter is reset. This limits the number of times the button can be registered as being pressed in a given period of time. It's good to visualise this as a pulse or beat, which opens and closes a gate while calls are being sent to the throttle.
Rate limiting is another way to think of a throttle.
Why is this such a common cause of confusion?
In many many use cases a debounce or throttle will get you the results you want, especially if the software implementation you're using allows you to chain, trail, or lead your throttle / debounce.
Still, I hope all the answers here and this one have helped you understand more clearly.
They're very similar.
This article explains it rather well and has graphics too.
https://css-tricks.com/debouncing-throttling-explained-examples/
From the article (and with some clarifications):
The main difference between this (throttle) and debouncing is that throttle guarantees the execution of the function regularly, at least every X milliseconds.
Normally debounce calls the function at the end of a specified time and throttle calls when the first call to the throttled function is made. Sometimes debounce can take extra config that changes this to do the call at the beginning instead. Some implemenations of debounce can actually do what throttle does (see Lodash source code) when called with specific configs.
Simple concept for throttle is clicking the submit button frequently in a form, we need to use throttle. So the submit function is prevent from frequent clicks. It saves the same requests pass into the function.
And about debounce, write a simple code with input text tag for searching some data from the server. oninput, you use the debounce so it removes the previous requests and pass the last typed word to the server
const throttle = (callback, time = 0) => {
let throttle_req, count = 0;
return async function () {
var context = this, args = arguments;
if(throttle_req) return;
throttle_req = true;
if(time > 0)
{
callback.apply(context, args);
setTimeout(() => {
throttle_req = false;
}, time || 200)
}
else
{
let response = await callback.apply(context, args);
throttle_req = false;
return response;
}
}
}
const debounce = (callback, time = 0) => {
let debounce_req;
return function () {
var context = this, args = arguments;
clearTimeout(debounce_req)
debounce_req = setTimeout(() => {
debounce_req = null;
callback.apply(context, args);
}, time || 200)
}
}
How we call: Just wrap your function with throttle or debounce to check the difference
Throttle ex: same button click more than 1 time
var throttleFunct = throttle(function(num) {
console.log(num, "hello throttle")
}, 2000);
throttleFunct(300) //it execute. because its the first call
throttleFunct(400) //it won't execute
throttle async without time
var getDataAsync = throttle(function(id, name) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({name: name, id: id})
}, 2000)
})
});
async function test() {
let response = await getDataAsync(120, 'Sherley').then(resp => resp)
console.log(response, "respond") //it execute. because its the first call
response = await getDataAsync(120, 'James').then(resp => resp)
console.log(response, "respond2")//it executes 2 after first request
response = await getDataAsync(120, 'Jonathan').then(resp => resp)
console.log(response, "respond3")//it executes 3 after second request
}
test()
Debounce For ex: search box autocomplete
var debounceFunct = debounce(function(num) {
console.log(num+1)
}, 2000);
debounceFunct(300) //it won't execute and it cancelled
debounceFunct(400) // it executes and it replaced with the previous call. because this is the latest event fire
The major difference between debouncing and throttling is that debounce calls a function when a user hasn't carried out an event in a specific amount of time, while throttle calls a function at intervals of a specified amount of time while the user is carrying out an event.
What really matters here, in most simple terms: if you have some action, that is continuously repeated for some period (such as mouse movement, or page resize events), and you need to run some function in response, but you don't want to react to every action (cause it may detriment the performance), you have 2 options:
debounce - you skip all incoming actions, except the last one (the 'last one' is defined by the 'wait' time period you set for debounce function, for example, 2s - it will consider that actions flood stopped, if no actions were taken for 2s, and then it will react. This strategy is reasonable if you don't care about regular updates, you just need to react at least once.
throttle - if you want to react 'on schedule', to make regular updates even if actions flood is endless, you make your function run at regular intervals (no more often, then the specified time interval), for example 2s throttling will mean that your response will be executed an once if action is taken, but no less then 2s after that. So with continuous actions flood your response will be run on 0s, 2s, 4s, 6s, 8s...

Why reseting setInterval it continues to call multiple function instance not one?

I have problem to pause and play setInterval, whenever I clearInterval and var = setInterval(func,time), it multiplies the instances on interval, and it starts to call 2 func per tick and so on.
Here is jsfiddle with non-working example http://jsfiddle.net/wZWWT/
Here is the code:
function test() {
$(".container").append("<div>Inserted text</div>");
}
var timer = setInterval(test,2000);
$(".container").on("mouseenter mouseover",function(){
clearInterval(timer);
}).on("mouseleave mouseout",function(){
timer = setInterval(test,2000);
})
Makes sense. Mouseleave and mouseout are two different events. So you've got two intervals created.
When you create a new interval the old one isn't destroyed. It continues working even if you don't store the reference to it
before setting a new interval try to check if you've another interval running:
$(".container").on("mouseenter mouseover",function(){
clearInterval(timer);
}).on("mouseleave",function(){
if ( !timer ) timer = setInterval(test,2000);
}).on("mouseout",function(){
if ( !timer ) timer = setInterval(test,2000);
})
The timer is actually just an integer that represents the setInterval(). If you assign a new setInterval() to it, then timer will have the ID of the new setInterval() but the old one is not cancelled, and you don't know the ID for it to do so with the ID overwritten.
In your code the on() is calling both mouseenter and mouseover - both are firing but only the ID of the last one to execute is set to the timer variable, so when it is called (twice, but it doesn't really do any harm) in your mouseleave/mouseout it can only cancel one of them.

prevent javascript setInterval function stacking up

I have a function that runs on a click event that uses javascript's setIterval for some of my animations (i'm doing a game) so the problem is that if a user clicks while the animation is still displaying (setInterval is still executing) the setInterval is stacking up in the event stack or that is what I found out thus either crushing my game or running twice as fast (the animation). My question is is there any way to prevent event stacking? I do not want the setInterval to stack up on the previous setInterval and so on. I know that I could use clearInterval function like so:
var timerInterval = setInterval(drawPlayerRunning, 50);
clearInterval(timerInterval);
but it does not really work as I want it to, because what if user clicks many times while the function is still is executing, the clearInterval will only get rid of last event of the event stack leaving all the previous ones still in the "game". Any idea how to prevent this event stack up, or at least removing them efficiently?
You can create a flag that monitors the interval state:
1)
var isIntervalInProgress = false;
setInterval(function()
{
if ( isIntervalInProgress )
return false;
isIntervalInProgress = true;
drawPlayerRunning();
isIntervalInProgress = false;
}, 50);
or just a timeout that will run itself once it's finished:
2)
var func = function()
{
setTimeout(function()
{
drawPlayerRunning();
func();
}, 50)
}
whichever you like
You want to use requestAnimationFrame. It is designed with games in mind, and if your code happens to be too slow, it will reduce your frame rate accordingly (from 60 fps to 30 fps for instance). But it won't stack-up events.
Edit: Sorry, I think I misunderstood your question. Let me try again.
You should have only one draw function which is called every few milliseconds (set the interval up with requestAnimationFrame(draw)).
A click should not add a new interval, but rather create a floatingAnimation object and add it to the list of objects to render. All animation objects will be rendered by the draw function everytime the browser calls draw. In the arguments passed to draw, there will be a timestamp. Use this timestamp minus the creation date of floatingAnimation to determine how to draw the floating thing above the character.

jQuery - When not keyPress(), keyUp() for 2 secs do function()

How can you set the opposite of keyPress, keyup, keydown etc. Something like if the user starts to type something and then stop, after 2 seconds do function(){}
I tried onKeyPress with delay but it doesn't seem to work.
Thanks
You can use keyPress and a global timer. Just reset the timer every time the user press a key.
I guess the code is something like:
var myTimer = undefined;
var delayTime = 2000; // should be in miliseconds.
function myfunction() {
// do your stuff here
}
function onKeyPress(e) {
if (myTimer) {
clearTimeout(myTimer);
}
myTimer = setTimeout('myfunction();', delayTime);
}
PS: I have not tested this code.
On a key event, you set a 2 second timer. If another key event comes in before the timer goes off, you stop the timer and set a new one. If the timer fires, then there's been 2 seconds of no typing.
Well, one oldschool way to do it is to use setTimeout and clearTimeout. Basically, every time a keypress happens, you cancel the previous timeout, and then set up a new one with a 2 second delay. The function call will only actually go through once someone stops pressing keys for 2 seconds, which I think is what you've asked for
I don't know whether any native way of doing this. But i have used this plugin to perform this.

Categories