How Does Setinterval and Settimeout Work

setInterval' vs 'setTimeout'

setTimeout(expression, timeout); runs the code/function once after the timeout.

setInterval(expression, timeout); runs the code/function repeatedly, with the length of the timeout between each repeat.

Example:

var intervalID = setInterval(alert, 1000); // Will alert every second.
// clearInterval(intervalID); // Will clear the timer.

setTimeout(alert, 1000); // Will alert once, after a second.

javascript - setTimeout() vs setInterval()

The main diffrence is

setInterval fires again and again in intervals, while setTimeout only fires once.

you can get more differnces in simple words in

setTimeout or setInterval?

'setInterval' vs 'setTimeout'

setTimeout inside setInterval does not work well

  1. The interval starts
  2. 1 second later the interval resolves:
  • classes are switched over
  • the timeout is triggered

  1. 1 second later:
    • The timeout resolves
      • classes are switched over
    • The interval resolves
      • classes are switched over
      • the timeout is triggered

You probably want the timeout time to be half the interval time, not the same as it.


A better approach entirely would be to use one class and use jQuery().toggle to toggle it on and off every second (using one interval and no timeouts).

How to deal with setTimeout in setInterval within a closure

Using setTimeout will not solve your problem. It's just logical. What setTimeout does is delay execution of something. So if you have a setInterval 100 times per second (every 10 milliseconds) and you call setTimeout inside it all you are doing is call setTimeout 100 times per second which will still print hello world 100 times per second:

 100 times per second            100 times per second

setInterval
setInterval ╲
setInterval ╲╲
. ╲╲╲ 1 second later
. ╲╲╲
. ╲╲╲
╲╲╲______________ setTimeout
╲╲______________ setTimeout
╲______________ setTimeout
.
.

The solution is to count how many time you've been called and print hello world every 100 times setInterval calls your function. Let's start with the most simple way to do this: global variables:

var counter = 0;

function doSth(fn) {
counter ++;
if (counter >= 100) { // once per second
counter = 0;
fn();
}
}

This works, however we've introduced a global variable which is ugly. Fortunately we know that the setInterval will not be calling our function directly. Instead it expects our function to return another function which it will call:

const fn = doSth(...);

Which means we need to write our function like this:

var counter = 0;

function doSth(fn) { // <──┐
return function(){ // <──┴─ oh look, a closure!
counter ++;
if (counter >= 100) { // once per second
counter = 0;
fn();
}
}
}

This is very fortunate because closures are a mechanism that allows functions to share local variables. Basically it makes local variables behave a bit like global variables but does not pollute the global namespace. Now we can simply move the global variable into the closure:

function doSth(fn) {

var counter = 0;

return function(){
counter ++;
if (counter >= 100) { // once per second
counter = 0;
fn();
}
}
}

How can a script and setTimeout/setInterval work together in NodeJS?

let's do this by example

setTimeout(function(){
print('there');
});

print('hi');

this will print hi then there

here's what happen

the script will be proccessed until last line and when ever it finds a timer function
it will add it to a queue which will be handled later at the end of the execution by the queue scheduler

loop queue => [ setTimeout ]

before exit there should be a scheduler, some kind of a loop to check if we
have something in the queue and handle them, then once queue is out of all timers the loop
will exit.

let's suppose we call setTimeout inside setInterval

setInterval(function(){
setTimeout(function(){
print('hi')
}, 500);
}, 1000);

loop queue => [ setInterval ]

after 1000 ms

setInterval will be fired and the inner setTimeout will be added to the queue

loop queue => [ setTimeout, setInterval ]

now we get back to the main loop which will wait for another 500 ms
an fire the inner setTimeout function, then remove it from the queue
because setTimeout should be run once.

loop queue => [ setInterval ]

back to the main loop, we still have items in the queue, so it will wait
another 500 ms and fire again ( 500 + 500 = 1000 ms)
the inner setTimeout function will be added to the queue again

loop queue => [ setTimeout, setInterval ]

back to the main queue agin and again ...

Now this is simply how timers work, they are not meant to handle blocking code, it's
a way to run code at some intervals

setInterval(function(){
// do something long running here
while (1) {}
setTimeout(function(){
print('hi')
}, 500);
}, 1000);

main loop will block here and the inner timeout will not be added to the queue, so this
is a bad idea

nodejs and event loop in general are good with network operations because they don't block when
used with select for example.

setInterval(function(){
// check if socket has something
if (socketHasData( socket )){
processSocketData( socket );
}

// do something else that does not block
// maybe schedule another timer here
print('hello');
}, 1000);

libuv which is the event loop used in nodejs, uses threads to handle some
blocking operations like IO operations, open/read/write files

JavaScript setInterval and setTimeout

setTimeout as well as setInterval only register functions (callbacks) but then go straight to the next command.

Therefor Hi and Hola are printed before the first callbacks are called.

First callback will be that of setInterval after 1 sec, then again after 2 sec.. After 3 seconds setTimeout kicks in and clears setInterval.



Related Topics



Leave a reply



Submit