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
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
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.
console.log("Beginning");
is executed.Test(tstCallback)
is called.Test()
function, a timer is scheduled. This registers a timer internal to the JS engine.Test()
continues, console.log("After Setting Timer");
is executed and then that function finishes.console.log("Something that is asynchronous");
line and then calls callback()
.tstCallback
function is then called and console.log("Should come last");
is executed.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);