Reputation: 1222
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
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:
getData
.getData
does its internal stuff and returns undefined
.document.getElementById
.getData
gets its data and the browser or other environment executes the callback function passed to it before.writeData
.There are many ways that can create an async function, such as events, AJAX, and other timers (setTimeout/Interval
).
Upvotes: 1
Reputation: 10557
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 functiongetSomeData()
Correct. This is synchronous (line-by-line) execution.
the
document.getElementById...
statement is allowed to execute before thegetData
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