Jamex
Jamex

Reputation: 1222

JavaScript code execution sequence for callback and contradictions to normal execution sequence

I can't seem to reconcile the technical flow of javascript execution sequence and the concept of callbacks. I have been using callbacks, but I am not happy with the execution flow because it appears that there are contradictions between idea of callback and the sequential JavaScript execution. This link http://cwbuecheler.com/web/tutorials/2013/javascript-callbacks/ explains callback and give examples, but I as I follow the code, I see a contradiction.

getData('http://fakedomain1234.com/userlist', writeData);

document.getElementById('output').innerHTML += "show this before data ...";

function getData(dataURI, callback) {
    var myData = getSomeData(); // fake function
    callback(myData);
}

function writeData(myData) {
    document.getElementById('output').innerHTML += myData;
}

My question/observation is that inside the function getData, the callback(myData) statement does not get executed until after the function getSomeData() is finished and returned a value to the variable myData, but then the contradiction occurs when the document.getElementById... statement is allowed to execute before the getData function call is finished executing.

Am I missing something?

Upvotes: 1

Views: 247

Answers (2)

Derek 朕會功夫
Derek 朕會功夫

Reputation: 94319

document.getElementById cannot be executed before getData gets completely executed, unless getData is asynchronous. By seeing there's a URL passing to getData tells me you are doing AJAX which is asynchronous.

Although your code won't behave like you said (it's synchronous!) because var myData = getSomeData() is synchronous, pretending the whole getData function is async and the flow goes like this:

  1. Executes getData.
  2. getData does its internal stuff and returns undefined.
  3. Proceeds to document.getElementById.
  4. Later getData gets its data and the browser or other environment executes the callback function passed to it before.
  5. Executes statements inside writeData.

There are many ways that can create an async function, such as events, AJAX, and other timers (setTimeout/Interval).

Upvotes: 1

kdbanman
kdbanman

Reputation: 10557

Synchronous vs. Asynchronous Execution

I think you're getting those two things mixed up. I'll quote and correct you below:

the callback(myData) statement does not get executed until after the function getSomeData()

Correct. This is synchronous (line-by-line) execution.

the document.getElementById... statement is allowed to execute before the getData function call is finished executing.

Incorrect. Again, this is synchronous execution - 'show this before...' will be inserted after the data.

You're likely thinking about callbacks in the context of asynchronous execution. Compare your synchronous code to this asynchronous version, which does insert 'show this ...' before the contents of myData:

getData('http://fakedomain1234.com/userlist', writeData);

document.getElementById('output').innerHTML += "show this before data ...";

function getData(dataURI, callback) {
    //var myData = getSomeData();
    //callback(myData);
    getSomeDataAsync(callback);
}

function writeData(myData) {
    document.getElementById('output').innerHTML += myData;
}

The change is in the getData function. callback is passed as an argument, rather than called immediately with the () operator.

The getSomeDataAsync function is asynchronous, meaning it will pop itself in the run loop's "background" before executing your myData callback. It won't run your callback until the event it is waiting for fires (i.e. when data retrieval completes). While getSomeDataAsync is waiting, execution resumes on the code that called it, which will insert your 'show this before...' immediately.

When the completion event fires, execution will resume, and the passed callback parameter will be executed. The contents of myData will then be appended!

Check out this fiddle to see what I mean

Upvotes: 1

Related Questions