I have a synchronous function inside setInterval() where I have set the timeout to 1 second. At times, the synchronous function inside setInterval() takes 30+ seconds to execute. Meaning, the function defined inside setInterval() is taking more than timeout set. Recently, I have been facing lot of issues inside this function which im not able to track.
Can anyone tell me if it is a problem when function inside setInterval takes more than the timeout? Or if theres any other ideal way to keep on calling a function whose execution time is unpredictable?
Sample Code:
myFunction = async()=>{
// Some synchronous external API calls which takes 30+ seconds to execute
}
setInterval(myFunction,1000)
Related
setTimeout(function(){
console.log("m");
}, 0);
console.log("s");
Why does this code print "s" before "m", even if the setTimeout callback is supposed to wait for 0 ms?
A browser or node.js always run a single threaded event loop to run your code. On the first run it will always run your synchronous code but may also que up asynchronous events that will call back later. Thats why we call the function here callback function it will be called later.
setTimeout is a microtask.
That means the function that you see isnt gona executed immedantly, it is gonna first queued up and will be executed within the next event loop.
Also a sidefact: 0 ms just means it will minimum wait 0 ms not exact 0
When you create a promise, or call an async function, or set a timeout for 0 milliseconds, the function is immediately queued into the Javascript event loop. Essentially, the function is added to a queue of functions to call, and once the javascript interpreter has nothing to do it'll start calling those functions. So, when you set a timeout for 0 milliseconds, it queues the console.log("m"), then calls the console.log("s"), then it has nothing to do so it finishes the queued console.log("m"), which is why it's out of order.
it just because JS is single-threaded and event loop works that way.
setTimeout has written in a way that it will send you function or whatever you want to do in a callback queue.
and then move forward to the next line, once next line executed it will not run your setTimeout part, or in other words, it will not process the setTimeout part until the stack is not empty.
so this is your code, and it will execute like this.
setTimeout(function () {
console.log("m");
} , 0)
console.log('s');
the first line will execute and it will send the inner part of setTimeout to callback queue and move to the 2nd line.
while 2nd line is executing the setTimeout part will wait till the stack is not emplty and as soon as 2nd line finishes execution,
the setTimeout part will execute,
maybe it's confusing by words, let's see this in action. I bet you can not get a better example than this to understand it, it's explained in the best way by Philip robert.
because JS code goes in order one by one. When you specifying setTimeout to 0 is still waiting, in C++ lang this would be something like this 0.000000245ms, and JS runs often on C++/C browser.
try this simple example
for (let x = 0; x < 500; x++) {
setTimeout(() => console.log(x), 0);
}
console.log('hello');
So we all know setTimeout waits a certain amount of time before executing something. My question is, does it wait for the above code to finish executing first, before waiting a second to execute something else, or does it just wait for a second, and whether or not the above code has finished executing, it executes the rest of the code anyways?
if (1 == 1) {
//huge chunk of code
} //end of if (1 == 1)
var theTime = 1000;
var timeout = setTimeout("location.reload(true);", theTime);
function resetTimeout() {
clearTimeout(timeout);
timeout = setTimeout("location.reload(true);", theTime);
} //end of function resetTimeout()
My goal is to get the first part of the code to finish executing, then refresh the page as soon as the first part of the code has finished executing. Is there a way to do that?
In your case, the page will reload 1 second after setTimeout was called. So it's the "huge chunk of code" time plus 1 second.
To refresh the page as soon as the first part of the code finishes, just call location.reload without setTimeout:
if (1) {
//huge chunk of code
}
location.reload(true);
EDIT: This approach doesn't wait for asynchronous code to finish. For example, the program below is interrupted by the reload before the alert box pops up.
if (1) {
setTimeout(() => alert('Test'), 1000);
}
location.reload(true);
If you setTimeout to a very small value (e.g. 1ms, possibly even zero, but haven't checked that) it will execute as soon as your main code is finished. It won't execute before your main code is finished, because JavaScript is not multi-threaded.
JavaScript is single-threaded and non-preemptive, it's not possible to interrupt code that's running. Asynchronous code, such as timeouts and AJAX callbacks, cannot run until the currently executing code returns to the main event loop.
The timer in setTimeout starts immediately when it's called. But because of the single-threaded design, the callback can't be called until all your current JS finishes. If that takes longer than the timer, then the callback will be delayed. So all you're guaranteed is that the callback will be called in at least that amount of time -- it might be longer, but not shorter. There could also be other asynchronous callbacks ahead of it in the event queue.
I am new(2 days!!) to the world of JavaScript and my only prior coding experience is in Java where execution of statements takes place sequentially.
I understand that or at least I've read that JavaScript is asynchronous which means that if there is a statement that takes a long time to execute, the next statement is executed without holding up the program for the first statement.
I came across callbacks(a lot actually!!) but I couldn't see how they could be used to determine the order of execution. I wrote a piece of code just to understand how it could be done and I sure could use some help.
console.log("Beginning");
function Test(callback){
setTimeout(function(callback){
console.log("Something that takes a lot of time");
},5000);
callback();
}
function tstCallBack(){
console.log("Should come last");
}
Test(tstCallBack);
What I want is for the output to display -
Beginning
Something that takes a lot of time
Should come last
But the output I am getting is -
Beginning
Should come last
Something that takes a lot of time
Is there anything I can do to get the output in the way I want it?
Let's clear some things up in what you said:
I am new(2 days!!) to the world of JavaScript and my only prior coding
experience is in Java where execution of statements takes place
sequentially. I understand that or at least I've read that JavaScript
is asynchronous which means that if there is a statement that takes a
long time to execute, the next statement is executed without holding
up the program for the first statement.
This is not how it works. A given function is either asynchronous or its synchronous by design. It has absolutely nothing to do with how long it takes to execute. You can have a very quick async function or a very long synchronous function. What determines whether the function is asynchronous or not is how it is designed. If it uses async I/O or timers or any other async infrastructure, then at least some of the execution of the function is asynchronous. That means that some of the function will finish LATER and some of the code right after this function call will execute BEFORE the async portion finishes.
I came across callbacks(a lot actually!!) but I couldn't see how they
could be used to determine the order of execution. I wrote a piece of
code just to understand how it could be done and I sure could use some
help.
Callbacks are used to notify the calling code when some asynchronous operation has completed. This can be used either to consume the result of the asynchronous operation or can be used to execute the next piece of code that wants to run in sequence after the async operation has finished.
In your code example, if you want the desired sequence, then you must call the callback inside the setTimeout() callback so that it gets called AFTER the setTimeout() called executes, thus giving you the desired sequence.
You also have to remove the callback argument to the setTimeout callback. That callback is not passed with that argument so declaring it there is just wrong. It can be accessed directly from the parent function via a closure as shown here:
console.log("Beginning");
function Test(callback){
setTimeout(function(){
console.log("Something that is asynchronous");
// call the callback here to indicate to the calling code
// that the asynchronous operation is now complete
callback();
},5000);
console.log("After Setting Timer");
}
function tstCallBack(){
console.log("Should come last");
}
Test(tstCallBack);
This will generate a sequence in the console of:
Beginning
After Setting Timer
Something that is asynchronous
Should come last
Conceptually, the Javascript engine runs a single thread and that single thread uses an event queue. So, in your function above, this is what happens.
The first console.log("Beginning"); is executed.
Test(tstCallback) is called.
As part of executing the Test() function, a timer is scheduled. This registers a timer internal to the JS engine.
The execution of code in Test() continues, console.log("After Setting Timer"); is executed and then that function finishes.
The current thread of JS execution finishes and if there is nothing else in the event queue, then the JS engine has nothing to do, but wait for the next event to occur.
Some time later (the 5 seconds that your timer is set for), the internal timer fires and it puts the timer event in the JS event queue.
Since there is no other JS executing at the moment, the timer event is pulled out of the event queue and executed. This means that the original callback that was registered for the timer is called.
As the timer callback is called, it executes the console.log("Something that is asynchronous"); line and then calls callback().
Your tstCallback function is then called and console.log("Should come last"); is executed.
The async event finishes execution and the JS engine looks to see if there are any more events in the event queue. If so, the next event is pulled out of the queue and it is run.
There are a number of very good references on how Javascript handles asynchronous operations:
How does JavaScript handle AJAX responses in the background?
How Javascript Timers Work
Do I need to be concerned with race conditions with asynchronous Javascript?
A lot of what you've said is wrong. JavaScript is sequential in the same way as Java, but asynchronous calls are made more often. If you want your callback to be called after the long thing, you must call it after the long running program. Like so -
console.log("Beginning");
function Test(callback){
setTimeout(function(callback){
console.log("Something that takes a lot of time");
callback();
},5000);
}
function tstCallBack(){
console.log("Should come last");
}
Test(tstCallBack);
I have modified your code as below to get the desired output.
console.log("Beginning");
function Test(callback){
console.log("Something that takes a lot of time");
setTimeout(callback,5000);
}
function tstCallBack(){
console.log("Should come last");
}
Test(tstCallBack);
setTimeout takes a callback function that will be executed after the specified time interval
The use of setTimeout is the asynchronous part. When the above code is executed,first the "Begining" console statement is printed and then the Test function is called passing in a function that needs to be executed asynchronously after 500ms .
Place the callback inside setTimeout and not outside as the callback will be executed first before the setTimeout does as javascript won't wait for setTimeout execution(as JS is synchronous by nature) and executes the next line and hence you won't get the desired output.
console.log("Beginning");
function Test(callback){
setTimeout(function(){
console.log("Something that takes a lot of time");
callback();
},5000);
}
function tstCallBack(){
console.log("Should come last");
}
Test(tstCallBack);
Demo
I am very new to node.js. Am trying to understand what exactly is meant by 'asynchronous' in terms of node js.
In the above context I have the below code:-
function foo()
{
setImmediate(function two()
{
console.log(1);
});
setTimeout(function one()
{
console.log(3);
},0);
process.nextTick(function three()
{
console.log(2);
});
console.log(4);
}
foo();
can some one please explain me, in depth, as to what exactly would be the order of execution for all of the above timer APIs and WHY will it be so? Any explanations/references regarding the call back stack etc. will also be helpful.
First of all, 4 gets logged first because all other calls to setImmediate, setTimeout or nextTick delay the execution of a function to somewhere after the currently executing code. But they all do it differently:
setTimeout
This function allows you to do something after a specific amout of milliseconds. If the milliseconds you pass to this function are less that 1ms, it will always wait 1ms before calling your function.
setImmediate
This function allows you to do something after node has processed all i/o events. Node processes i/o events in every cycle of the event queue. So setTimeout will always execute your function in the next cycle of the event queue. This allows the queue spin unblocked.
process.nextTick
This function allows you to do something immediately after the currently running code finishes. You can imagine it like you would be able to modify the currently executing code and add some lines after it, so that it does something more before it's finished. Calling this function again and again does block the event loop because it cannot go on to the next task in the queue, since it's still busy with the current one. This means, node does not process the i/o events until the last function you passed to nextTick got executed. Therefore you should never call this function recursively or use it too much, because it can stop the event loop from spinning. Node will display a warning if this happens, though.
So.. to explain the output of 4 2 1 3:
4 is the first log that's not getting delayed and thus is the first output.
2 is getting logged immediately after foo() finishes and thus is the second
3 is faster than 1 because a usual event loop cycle is much faster than 1 millisecond, and so.. 3 is the third log
setTimeout delays by at least 1ms which is the longest delay of all the delay functions. It's clearly the last.
This question already has answers here:
Why is setTimeout(fn, 0) sometimes useful?
(19 answers)
Closed 9 years ago.
I have problem when using jQuery plugin tablesorter and I can't call trigger twice.
For example this won't work:
this._$table.trigger('update');
this._$table.trigger('sorton', [[[1,1]]]);
But this works:
this._$table.trigger('update');
setTimeout($.proxy(function() {
this._$table.trigger('sorton', [[[1,1]]]);
}, this), 1);
And then I see that problem was in trigger 'update', it call method with body:
function () {
var me = this;
setTimeout(function () {
// rebuild parsers.
me.config.parsers = buildParserCache(
me, $headers);
// rebuild the cache map
cache = buildCache(me);
}, 1);
}
Why did the tablesorter developer use setTimeout with one millisecond?
Short asnwer: Function execution queueing
This is the short answer to your question. setTimeout with either 0 or 1 millisecond is used for function execution queueing. Read on to find out why and how.
Javascript has single threaded execution
Javascript engine is a single threaded process. So whenever developers wanted to defer some function execution to get executed right after the current one that's just being executed, a setTimeout is being used to actually queue the next function... It doesn't have anything to do directly with events although functions may be event handlers. The only event in this equation is the timeout event that setTimeout creates.
This is an example of two functions where the first function during its execution queues a second function to be executed right after it.
function first()
{
// does whatever it needs to
// something else needs to be executed right afterwards
setTimeout(second, 1);
// do some final processing and exit
return;
}
function second()
{
// whatever needs to be done
}
So to javascript engine thread the execution queue looks like this:
first()
second()
Mind that this has nothing to do with function call stack.
Why 1ms?
1ms is a very short amount of time, which (almost) assures that your second function will get executed right after your first function returns. You may see sometimes even 0ms which actually executes it right after first function returns.
If one would on the other hand use longer time i.e. 100ms this could result in a different function getting executed in the meantime and that could have an undesired effect on the whole UI process.
Why function queueing in the first place?
Browsers nowadays prevent client side functionality to hang current browser session by observing long running functions. If a particular function runs long enough, browser Javascript execution engine will pause it and ask the user whether they want to terminate it (kill it) or wait for it to complete.
This is usually undesired effect when you actually do have a long running function. For instance imagine you have a function that has to loop through a large number of items processing each one during the process. You definitely don't want the user to terminate the process because the loop needs to execute.
What's the solution in this case? In such case instead of having a single function with loop and executing it, you'd rather have the loop (queueing) function that would then queue function calls for processing each item. This is just an outer skeleton of such functionality.
function queueItems(items) {
for(var i = 0; i < items.length, i++)
{
setTimeout((function(item) {
return function() {
processItem(item);
};
})(items[i]), 0);
}
}
function processItem(item) {
// process individual item
}
This way you'd prevent your functions to run too long and after each executed function control would get back to Javascript engine resetting its function-hang timer. But be aware that while your functions are being executed your UI will likely be unresponsive or at most unpredictable. It may be better to queue your function with some time space in between so UI stays responsive if that's desired.
It's an old hack. If an event needs to be triggered after another event you can use setTimeout with 1ms to make sure the event is triggered after the other event.
I think that since trigger('update') internally has a setTimeout, only by setting another setTimeout you can achieve the desired order of statement execution. If you don't call 'sorton' through setTimeout it will be executed before 'update'.
On the other hand I guess 'update' uses setTimeout for preventing 'update' from being a blocking function when it may take a long time to be executed.