1

Let's take this for example:

function test(i, total) {
    return total + i * 100 / 999 * -124 / 333;
}
var total = 0;
for (var i = 0; i <= 100; i++) {
    total = test(i, total);
    console.log(total);
}

When testing it, I see that it works synchronously -- the for loop will wait until test(i, total) has returned its value before going through the next iteration.

However there are other cases where a loop would keep on going and even finish, before a function was even done doing its function. If the test function took 3 seconds to return, why does the loop wait on that? Is it because there is nothing of async nature in the test function? I tried setting a setTimeout of 3 seconds in the test function and then I'd get undefined from the console log.

Dan P.
  • 1,707
  • 4
  • 29
  • 57
  • Invocation in _JavaScript_ is blocking, but _JavaScript_ doesn't have a blocking wait/sleep method and instead uses a non-blocking callback for that. Logic. – Paul S. May 14 '14 at 17:14

3 Answers3

1

Function calls are synchronous and single threaded in Javascript. This is per the language design. When you call the test function from the loop, the loop waits till the function returns.

When you call setTimeout, it creates a timer and returns immediately. It does not wait for the timer to be triggered (even for the first time). The timer is triggered asynchronously.

For more info, see Is JavaScript guaranteed to be single-threaded? and read about web workers.

Community
  • 1
  • 1
Nivas
  • 18,126
  • 4
  • 62
  • 76
1

"If the test function took 3 seconds to return, why does the loop wait on that? Is it because there is nothing of async nature in the test function?"

Exactly. The execution of functions is synchronous in Javascript, like in almost every other language. The execution is done along a single path, so when you call a function it will complete before returning and the code after the call can continue.

If you use asynchronous code in a function (for example with setTimeout), then the asynchronous code will be put on hold until the rest of the code has executed and the browser get the control back, as Javascript is single threaded.

If you call test 101 times in your loop and it uses setTimeout each time, then there is 101 pieces of code that waits to run while the loop completes. Those 101 pieces of code can not run until after the loop has completed. The code that you have put on hold can't provide a value to return from the function, as the function returns before the code can run.

To run code asynchronously you would use a callback that gets called when the function has completed. Example:

function test(i, callback) {
  window.setTimeout(function(){
    var result = i * 100 / 999 * -124 / 333;
    callback(result);
  }, 1000);
}

var total = 0;
var resultCount = 0;
for (var i = 0; i <= 100; i++) {
  test(i, handleCallback);
}

function handleCallback(value) {
  total += value;
  resultCount++;
  if (resultCount == 101) {
    console.log(total);
  }
}

Demo: http://jsfiddle.net/7VgWV/

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

It's because JavaScript is single-threaded. Your code is single-threaded.

ktm5124
  • 11,861
  • 21
  • 74
  • 119