0

I always thought that javascript is a single threaded language (for the most part at least).

As you can see in my code:

<html>
<body>

<a onclick="test();">test</a>

</body>
<script>
var text = "test";
function show()
{
    console.log("show(): "+ text);
}
function test()
{
    console.log("before: "+text);
    change();
    console.log("after: "+text);
    show();
}
function change()
{
    text = stateChange(-1);
}
function stateChange(newState) {
    var output = "empty";
    setTimeout(function () {
        if (newState == -1) {
            alert('VIDEO HAS STOPPED');
            output = "newText";
            console.log("AFTER 5 Sec: "+output);
        }
    }, 5000);
    return output;
}

</script>
</html>

My stateChange function returns a variable already prior to completion of the function. It didn't wait 5 seconds before returning the variable to change() function. Therefore, all the functions inside the test() function were being executed (then of course after 5 seconds the alert shows up).

My question is, is there a way to return variable only when the function is fully completed. It seems like it javascript created another thread to execute other functions. Any way to go around this?

(This happens in ajax as well, where I will have a function i thought i will return after the completion of the ajax call, but turns out the function just return itself right away before finishing the ajax call.)

I want my test() function to work in order.

Ryan Fung
  • 2,069
  • 9
  • 38
  • 60
  • Yeah, the `change()` function needs to pass a callback function to `stateChange()` instead. – Ja͢ck May 28 '15 at 02:49
  • Singlethreaded it might be, but that doesn't mean it's not asynchronous. Your code does not run linear, the callback is executed *later* - after you `return`ed from the function. – Bergi May 28 '15 at 02:52
  • `setTimeout` **does not pause execution** and so the line `return output;` occurs almost immediately after `var output="empty";` `setTimeout` only adds an entry to a scheduling system, it does not sit around and wait... It should do exactly what you reported -- it executes the `function()` 5 sec later. Perhaps read https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout – Paul May 28 '15 at 02:56

2 Answers2

2

It is because setTimeout() is executed asynchronously, after creating a timer to be executed in the future the calling function will continue executing before the timeout handler is executed.

If you want to wait for 5 seconds and then execute something, then you can use a callback like

var text = "test";

function show() {
  console.log("show(): " + text);
}

function test() {
  console.log("before: " + text);
  change(function(data) {
    console.log("after: " + text);
    console.log('param', data)
    show();
  });
}

function change(callback) {
  stateChange(-1, function(output) {
    console.log('after change', output);
    text = output;
    callback(text)
  });
}

function stateChange(newState, callback) {
  var output = "empty";
  setTimeout(function() {
    if (newState == -1) {
      alert('VIDEO HAS STOPPED');
      output = "newText";
      console.log("AFTER 5 Sec: " + output);

      callback(output)
    } else {
      callback(output)
    }
  }, 5000);
}
<a onclick="test();">test</a>

How JavaScript Timers Work

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
1

The code in the function in the setTimeout call is executed after five seconds have passed. The stateChange function will complete execution after calling setTimeout.

user2182349
  • 9,569
  • 3
  • 29
  • 41
  • 1
    @RyanFung That *is* the case actually; the call to `setTimeout()` returns immediately. – Ja͢ck May 28 '15 at 02:52
  • 1
    @RyanFung: That's exactly what happens. Your only confusion is the fact that "after calling setTimeout" and "after setTimeout executes the function" are two different things. setTimeout returns immediately without waiting. So after calling setTimeout it returns without executing your function. 5 seconds later setTimeout executes your function but this is 5 seconds after it has returned – slebetman May 28 '15 at 02:52
  • my bad on that. Sorry, I misunderstood – Ryan Fung May 28 '15 at 02:59