Reputation: 347
For example I have these two functions:
var count= function(){
for(i=1;i<=3;i++){
console.log(i);
}
setTimeout(function(){
for(i=1;i<=3;i++){
console.log(-i);
}
},2000);
}
var letters = function(){
var charSet = 'abcdefghijklmnopqrstuvvwxyz'
for(i=0;i<3;i++){
console.log(charSet[i]);
}
}
When I execute them in this order:
count();
letters();
I expect to get as output:
1 2 3 -1 -2 -3 a b c
But what I get is:
1 2 3 a b c -1 -2 -3
Why the function does not wait the Timeout to finish? How can I achieve the desired behaviour?
Upvotes: 2
Views: 875
Reputation: 32511
Why the function does not wait the Timeout to finish?
Because that's not how setTimeout
works.
What actually happens is you put in a request to have your function run in no less than X milliseconds (2000 in your case). The JS runtime will wait for all other code to finish running then see if it's been at least X milliseconds. Once it has, your function will run. But in the meantime, you can run any other JS code. It intentionally doesn't block other code from running.
How can I achieve the desired behaviour?
The best answer is structure your code differently. You need to learn to work with asynchronous events. The simplest way would be to use a callback function:
var count = function(cb) {
for (i = 1; i <= 3; i++) {
console.log(i);
}
setTimeout(function() {
for (i = 1; i <= 3; i++) {
console.log(-i);
}
// Run the function we passed to it after the rest is done
cb();
}, 2000);
}
var letters = function() {
var charSet = 'abcdefghijklmnopqrstuvvwxyz'
for (i = 0; i < 3; i++) {
console.log(charSet[i]);
}
}
count(letters); // Pass `letters` as a callback so it will be called after `count` is done
Upvotes: 2
Reputation: 769
The reason that you aren't getting 1 2 3 -1 -2 -3 a b c
is because your code does not stop at the setTimeout(...)
call. This is because many JavaScript methods, by nature, are asynchronous. This means that they will not stop the flow of your code. That means when you call setTimeout(...)
, the JavaScript interpreter will make sure that the function passed into setTimeout
is run in 2000
ms, but does not stop and wait for it. It will continue on its normal execution flow, onto the next instruction.
If you wanted it to wait, you could put the letters()
call after you print out the remaining numbers (-1, -2, -3
).
setTimeout(function(){
for(i=1;i<=3;i++){
console.log(-i);
}
letters();
},2000);
Upvotes: 2
Reputation: 38816
Because setTimeout
schedules the second loop to run later (in ~2 seconds), then returns immediately.
Node.js is for asynchronous, event-driven programming. You do not want to be blocking execution at all - the behaviour you are asking for is not "desired" at all.
I suggest you read up about Node.js and asynchronous programming, then re-visit what it is you are actually trying to do. You probably want something more like this:
function count(callback) {
for (i=1; i<=3; i++){
console.log(i);
}
setTimeout(function() {
for(i=1;i<=3;i++){
console.log(-i);
}
callback();
}, 2000);
}
function letters() {
var charSet = 'abcdefghijklmnopqrstuvvwxyz'
for (i=0; i<3; i++){
console.log(charSet[i]);
}
}
And run it like:
count(letters);
Upvotes: 1