Race conditions with JavaScript event handling? - javascript

We understand that JavaScript is single threaded, but we want to confirm our understanding of asynchronous event handling in JavaScript. More importantly, we want to confirm we're not exposed to potential race conditions.
Conceptually, our mobile app works like this:
We invoke function foo when a mobile page is loaded.
At the end of foo, we use setTimeout to invoke foo again (with one second delay) if a counter is greater than 0. If the counter hits 0, we load a new page. The timeout is saved in a variable.
If a button is tapped, we invoke function do_tap and clear the timeout variable saved in step two (and do other stuff).
do_tap and foo both update the same page element, and we want to confirm that they wouldn't step on each other.
Questions:
Assume a tap occurs during the execution of foo. Will the browser queue do_tap to start executing after foo finishes? In other words, are we guaranteed that once foo starts, we can never see execution of foo and do_tap interleaved?
What if the tap occurs first? do_tap is guaranteed to complete before foo starts, right?

Except for web workers and cooperating frames or windows (which aren't being used here), Javascript is single threaded within a given window so there are never two threads of execution running at the same time in that window. As such, you don't ever have to worry about race conditions that might be a typical worry when using threads.
Under the covers, Javascript has an event queue. Your current thread of execution will run to completion and then when it completes, the javascript interpreter will check the event queue to see if there are more things to do. If so, it fires that event and starts up another thread of execution. Pretty much everything goes through that event queue (timers, key events, resize events, mouse events, etc...).
You can read more about it and see a bunch of relevant references in one of my other answers on this subject.

Event execution proceeds single-threaded until the event has been handled. Until that time, no other event loop will be initiated.
In other words, while a handler is running for some event, no other handler for any other event will interrupt it.
Thus the answer to both question 1 and question 2 is "Yes." (This is, of course, barring browser bugs, but if you take that into account you can't get very far. It's not like there are any synchronization primitives to fall back on. I say this only because there was a period of time during which Safari could fire a "DOMready" event in the middle of running another "DOMready" event handler. That was, however, quite clearly a bug.)

As long as the first thing Do_tap() does is clearTimeout there will be no chance for foo to be running during the execution of Do_tap(). However, if an asynchronous process was initiated in foo() such a database request then there could be a potential wait to access the database in Do_tap() as foo() finishes its request, and if foo() has a callback function that could theoretically be called after Do_tap() was done executing.

I didn't catch anyone else saying this, but I think the answer to #2 is that different browser implementations can and do differ in subtle ways as to which queued events are processed first. No, there is no possibility of interleaving, but whether setTimeout(func, 0) or a mouse event is handled first is not guaranteed by the language spec and in practice can matter. Whereas setTimeout(func, 100) is guaranteed to be processed later than pending events received during the currently handled event.
Just saying.

Related

Does the event loop run on same thread as the JS main thread?

I am trying to understand asynchronous JavaScript but one thing that I'm wondering is, does the event loop run on the main thread? If so, does all synchronous code in Main() have to go through the event loop? (E.g. does console.log("Hello") also have to go through the event loop?)
And is the event loop the only one who is allowed to push functions to call stack?
Yes, the event loop runs on the same thread as your main function.
No, the event loop doesn't start processing messages until your main function returns. console.log() is synchronous (although there may be some asynchronous processes involved in generating the console output, they have nothing to do with the event loop).
There is only one way that a function (or more accurately a function's stack frame) gets onto the call stack -- the function gets called by whatever is currently on the top of the stack. A function gets removed from the call stack when it returns or throws. In a thread, the function at the top of the stack is what's currently running.
The event loop is at the bottom of the stack, or at least it's underneath all JavaScript functions, so it only gets to run when all previously running JavaScript functions have returned or thrown.
Does the event loop run on same thread as the JS main thread?
JavaScript is often called single threaded, because different pieces of JavaScript can't run at the same time. (Although with the introduction of Web Workers, this isn't necessarily true anymore.) Whether you call this the "main" thread depends on your definition of "main". If you are asking about whether the event loop itself runs on the same thread as the messages it executes, than that would make sense, but this is implementation dependent.
JavaScript doesn't dictate any threading at all. It makes sense for implementations to use only a one thread for the event loop and the JavaScript execution because all the code will always run sequentially, but this isn't a requirement.
As for your questions about event loop and the call stack, you first need to understand how those two work.
The event loop is a simple mechanism that executes queued messages in order and if none are available, it will wait until a new one comes in. A message can be anything that isn't executed immediately. Such as (but not limited to) incoming events (such as clicks), responses from AJAX calls or a callback from setTimeout().
The call stack is the stack of function calls. When a function is invoked (directly, so not via the event loop), a new frame is added to the stack that will be executed. Once the function has completed, the frame is removed from the stack and the code of the previous frame will continue from the point it invoked the completed function. Once all functions are complete and the call stack is empty, the event loop will run the next message.
So to answer your remaining questions:
does all synchronous code in Main() have to go through the event loop?
Not directly. The event loop only invokes the message and wait for it to complete. It doesn't interfere with the execution of the message itself.
is the event loop the only one who is allowed to push functions to call stack?
The only time the event loop interacts with the call stack (or the "execution context stack" as the specification calls it), is when it "spins the event loop". In such a case, the call stack is copied for later use, some other task is performed and later the copied call stack is restored so the execution can continue from the point it left off. But this only happens on a handful of occasions.
Generally, frames are added to the call stack when a (synchronous) function is called. The event loop has little to do with that.
You can read more about the event loop on MDN.
Typically Javascript is single threaded,and the event loop doesn't run like code because it is not.
The event loop has one simple job as a mechanism, which is : To monitor the CALL STACK and CALL QUEUE, if the call stack is empty, the EVENT LOOP takes the first event from the QUEUE and will push it to the CALL STACK, which effectively runs it.
I hope this makes you see the EVENT LOOP from a different perspective.

where do the browser web api's run in Javascript?

where do the browser web api's run in Javascript like setTimeout ?
Do they run in some other environment or they take the help of javascript single thread ?
They run outside of the JavaScript runtime. Those "Web API's" are executed within the browser's Web API execution space.
setTimeout() for example, is a method of the window object (it can also be invoked as window.setTimeout()). window is not at all part of JavaScript (it's a browser object) and anything you ask the window to do for you is handled outside of the JavaScript runtime and by the browser's other capabilities. The request for the Web API call originates from within the JavaScript environment, but the execution of the API call actually runs outside of it.
This is the very reason that we can have asynchronous behavior in web applications. While the JavaScript runtime (which is a synchronous environment that can only do one thing at a time) is doing its one thing, the browser can be doing something else.
setTimeout(), alert(), navigator.geolocation, XMLHttpRequest are all examples of Web APIs that run outside of the JS engine.
Here are some other Web API's and here is a great video that explains this in the context of timers specifically.
The following series of events occur when the API calls are made:
When the browser makes an API call, the API call is placed in the call stack
API call is placed in the browser's web APIs stack for execution in the background
While the API call is being executed in web APIs background, the render queue tasks are passed to the call stack by the event loop (assuming all tasks in call stack are complete) - this means the render queue is not actively paused hence the browser is not freeze
Once the API call is completed, the results are placed to the callback queue
If the call stack is clear, the results of the API response are placed to the call stack and the API response handler is executed by the call stack
Do comment if you need any clarification
APIs in client-side JavaScript:
To understand how browser APIS works, first, you have to clear concept about execution stack, event loop and message queue
Client-side JavaScript, in particular, has many APIs available to it — these are not part of the JavaScript language itself, rather they are built on top of the core JavaScript language, providing you with extra superpowers to use in your JavaScript code. They generally fall into two categories:
Browser APIs are built into your web browser and are able to expose data from the browser and surrounding computer environment and do useful complex things with it.
For example, the Web Audio API provides JavaScript constructs for manipulating audio in the browser — taking an audio track, altering its volume, applying effects to it, etc. In the background, the browser is actually using some complex lower-level code (e.g. C++ or Rust) to do the actual audio processing. But again, this complexity is abstracted away from you by the API.
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction
<script>
const second = () =>{
console.log("How are you doing");
}
const first = () =>{
console.log("Hi there");
second();
console.log("The End");
}
first();
</script>
Above example is an example of Synchronous JavaScript, where the first function is executed, logs "Hi There!" to the console, calls the second function, which then prints "How are you doing?" to the console,
nd then finally "The end" is logged to the console One instruction after the other in a Synchronous way.
Now let's try by an example with setTimeout which is a web API. considering bellow example
<body>
<script>
const second = () =>{
setTimeout(()=>{
console.log("Async Hi there");
}, 2000)
}
const first = () =>{
console.log("Hi there");
second();
console.log("The End");
}
first();
</script>
</body>
Output:
Now above one involves some Asynchronous JavaScript. Again the first function gets called, logs "Hi There!" to the console, and then calls the second function. Now this function calls the Set Timeout function, which is basically like a timer that will execute the callback function that we passed into it, after 000 milliseconds. However, this will not make the code stop for two seconds, but instead, the function returns, goes back to the first function and logs "The end". Then after the two seconds actually have passed, Async "Hi There!" is logged to the console.
Now, why does the code move on, instead of waiting for the timer to finish?
Well, before I discuss with you how and why this actually works behind the scenes, let me quickly explain to you another example. Suppose we select an image from our DOM and pass it into a Process Large Image function,
that we created. We know that this function is gonna take some time
to process the image. And just like before we don't want the code to have to wait. So we don't want it to stop while the image is processing,
because that would be terrible in some situations. What we do here is to also pass in a Callback function, that we want to be called as soon as the function is done processing. And just like that we have created Asynchronous code.
That is the whole philosophy behind Asynchronous JavaScript. We do not wait for a function to finish its work, and then do something with the result. Instead, we let that function do its job in the background,
so that we can move on with the code execution. We then also pass in a callback function, that will be called as soon as the main function
has done whatever it had to do. We then move on immediately,
so that the code is never blocked. Which means that it can keep processing the code in a Synchronous way, line by line. Because if the code is actually blocked, then nothing really works on the page during that time.
For example you can't click any buttons, or anything like that. So, in summary, we can use callback functions to defer actions into the future.
In order to make our code non-blocking. But how does that actually work
behind the scenes of JavaScript? Well, that's where the Event Loop comes in. the Event Loop is part of the bigger picture of what happens behind the scenes of JavaScript, when we call functions and handle events like DOM events.
Event Loop, as well as the Web APIs, which together with the Execution Stack and the Message Queue make up our JavaScript runtime. This runtime is responsible for how JavaScript works behind the scenes as it executes our code. It's extremely important to understand how all these pieces
fit together in order to execute Asynchronous JavaScript.
Let's now take a look at how the code from the last example
is executed inside our JavaScript engine, line by line.
It starts by calling the first function, and as we already know,
an Execution Context for that function is put on top of the Execution Stack, which can also be called the Call Stack.
In the next line of code, the console dot log function is called and a new Execution Context is created and the text is logged to the console.
Then the function returns and the Execution Context pops off the stack.00
Moving on to the second function, a new Execution Context is created
and in the next line the Set Timeout function is called. Which causes yet another Execution Context to be created.
Now, before we move on, where does this Set Timeout function actually come from? It's part of something called the Web APIs. Which actually live outside the JavaScript engine itself. Stuff like DOM manipulation methods, Set Timeout, HTTP requests for AJAX, geolocation, local storage and tons of other things, actually live outside of the JavaScript engine
We just have access to the because they are also in a JavaScript runtime
This is exactly where the time will keep running for two seconds, asynchronously of course so that our code can keep running without being blocked.
When we call the Set Timeout function the timer is created, together of course with our callback function Right inside the Web APIs environment.
And there it keeps sitting unti it finishes its work all in an Asynchronous way.
The callback function is not called right not but instead it stays attached to the timer until it finishe
And since the timer keeps working basically in the background, we don't have to wait and can keep executing our code. Next up, the Set Timeout function returns, pops off the stack and so does the Execution Context of the second function Which now returns as well and we are back to the initial first function. Now we just log the end to the console
and we give ourselves a new Execution Context, print the text to the console and pop the text off again.
Next the function returns and we are back to our original state
Right now we have executed all our code in a Synchronous way,and have the timer run Asynchronously in the background. Let's suppose that our two seconds have passe and the timer disappear. But what happens to our callback function no Well, it simply moves to the Message Queue
where it waits to be execute as soon as the Execution Stack is empty
This is exactly what happens with DOM events.
In the case of DOM events our event listeners sit in the Web APIs environment, waiting for a certain event to happen And as soon as that event then happen then the callback function is placed on a Message Queue
ready to be execute.
Alright, so how are these callback function in the Message Queue executed
And that's where, finally, the Event Loop comes in. The job of the Event Loop is to constantly monitor the Message Queue and the Execution Stack,
and to push the first callback function in line onto the Execution Stack, as soon as the stack is empty. In our example here, right now the stack is empty, right And we have one callback waiting to be execute
And the event loop takes the callback and pushes it onto the stack
where a new Execution Context is created for that function.
That's what the event loop does. Inside that callback function now,
we simply run the log function, which logs Async "Hi There!" to the console. Then the context pops off the stack and we're done! Now if there were some callbacks waiting right now like data coming back from an AJAX request or the handler of a DOM even then the Event Loop would continue pushing them onto the stack until all of them were processed.

Do DOM Events Always Run Single Threaded?

So I answered a question recently and OP asked if I could add the following about DOM events to my answer:
Maybe you could also add to your answer that not only they are executed first, but the subsequent event is blocked until the first one finishes.
Well, can I add that? Do I know that with DOM events will run one event at a time and will wait for the previous one to finish before the next one starts?
Do I at least know this is always the case in browser JavaScript?
Finding a conclusive answer to this has been surprisingly difficult to be so far, I've expected a "yes" but I just can't find it.
Clarification: I'm not asking about adding other asynchronous handlers inside the handlers, or calling setTimeout or workers and such. All I'm asking is whether or not the order of event handler execution is guaranteed, and that the next one starts only the previous one finished executing ? A good answer would cite a credible source (preferably - a specification). Nothing about threading here.
Yes and no, all JS runs on the same thread, except for web workers, which don't have access to the DOM. http://dev.opera.com/articles/view/timing-and-synchronization-in-javascript/
Here's some relevant information on that page
All event handler functions are executed sequentially, and each event is processed completely (including bubbling up through the DOM and performing the default action), before the next event is processed.
However, later on that page, they mention
Race Conditions
Each window (and frame) has its own event queue.
In Opera, every window has its own JavaScript thread. This includes windows in iframes. The consequence is that event handlers initiated from different frames might execute at the same time. If these simultaneous scripts modify shared data (like properties in the top window), we have the possibility of race conditions.
Events all are put into an event queue, and all event handling happens within that same thread. Along with all asynchronous callbacks, like XHR and setTimeout.
Beware of nested events also, since many methods will execute if you fire an event and they could change global state. Example http://jsfiddle.net/rpxZ4/
$('#d1').click(function(){
alert('before ');
$('#d2').trigger('click');
$('#d3').trigger('click');
alert('after ');
});
$('#d2, #d3').click(function() {
alert('clicked ' +this.id);
});
Here are Opera's suggestions for dealing with timing
Don't have long-running scripts.
Don't use synchronous XMLHttpRequests.
Don't let scripts initiated from different frames manipulate the same global state.
Don't use alert boxes for debugging, as they might change the logic of the program completely.
Well, that actually depends on what do you do in your handler and how do you define 1st handler ended moment?
For example, if you're doing only sync operations in eventHandler1 then you're sure that eventHandler2 won't get triggered before eventHandler1 finishes. the reason is javascript being single threaded.
But, imagine scenario like this:
click on button1 triggers eventHandler1 which actually makes ajax request. in that scenario, what do you actually consider as 'end of eventHandler1'? if it is the moment when ajax request returns then certainly eventHandler2 will start (and possible end) execution before eventHandler1 finishes.
To put it short: whenever you do sync-only operations > the order is guaranteed.
Added from comments:
http://www.w3.org/TR/DOM-Level-3-Events/#sync-async for example, it says: " Each event in this virtual queue must be delayed until the previous event has completed its propagation behavior, or been canceled."
Well, now we're back to the question 'what type of events are we talking about'? As mentioned before: if it's async events then sure the order is not guaranteed. But the original dilemma was about click event and that one is not async but sync. And for sync events documentation clearly states: Events which are synchronous ("sync events") must be treated as if they are in a virtual queue in a first-in-first-out model, ordered by sequence of temporal occurrence, with respect to other events, to changes in the DOM, and to user interaction.
yep, no guarantees. now add javascript being single-threaded into play and you can't get them executing at the same time. but yes, speaking of DOM strictly - there is no guarantee whatsoever which one will happen before.
just one more comment... you might have exactly the same DOM but accessed from Java multi-thread environment. What then?:) then you have to implement your own thread-safe async events handling because you're no more 'protected' by single thread environment as you have with javascript. So, the conclusion, as i see it is that DOM specs does require that sync events are fifo implemented. for async events execution depends on stack/thread implementation. in Javascript, that means that 2 handlers can't overlap but in Java e.g. doesn't have to mean.

Are JavaScript functions asynchronous?

Consider the following function being executed,
function loadPage()
{
takeInput();
processInput();
outputInput();
}
In what order would they be executed(I have read that it follows stack so option 2 will be the answer)?
Option #1
takeInput();
processInput();
outputInput();
Option #2
outputInput();
processInput();
takeInput();
JavaScript functions are not asynchronous. Some very limited set of functions have an asynchronous API:
addEventListener, setTimeout, setInterval. These are the only 3 (which I thought was very surprising).
They allow you to pass in a callback that may get called eventually. Such as when a timer expires, or when a user clicks on something, or when an AJAX request completes.
JavaScript has an event loop. The event loop processes each event as it comes in. If you click a button 3 times and then a timer expires that will also be the order the events are handled. It is all very well defined and determined.
Furthermore, JavaScript doesn't have threads, it runs one event completely till there is nothing left to do (you return) before starting the next event. So events will never interfere in any way. This allows you to make very strong assumptions about the state of your data.
Are JavaScript functions asynchronous?
Some are, most are not.
In what order would they be executed
They will be executed in the order in which they are called. Since they are are all called from the same function, that will be in a simple linear order.
If any of them are written in an asynchronous way, then they might not finish all their activity in the same order. For example:
function a() {
console.log('a');
}
function b() {
console.log('b');
}
function c() {
console.log('c');
}
function aAsync() {
setTimeout(a, 500);
}
function load() {
aAsync();
b();
c();
}
load();
Javascript is not Asynchronous. It works Synchronously ,that is it runs one line of code at a time.
When javascript code is run , first a Global execution context is created and if you call a function from global execution context, another execution context is created by the javascript engine and that is placed at the top of the execution stack (global execution context is already in the stack)and if there is another function being called from inside that function ,another execution context is created and stack size keeps on increasing.
So,javascript engine keeps running this code one line at a time and in that process if there is any event/ http request fires, the browser puts them in the EVENT QUEUE. So, the point is javascript engine wont process the events in queue until the execution stack is empty.
And when the engine is done with the execution stack, it periodically looks if there is any event handler for current event in queue and similarly creates execution context for that handler and runs the code within.
So, the whole process is just synchronous and asynchronousity is just handled by the other parts of browser like(rendering engine or http engine) while the javascript engine continues to run the code synchronously.
So, in your case,
from whichever context function loadpage was invoked , its execution context was created and and placed at the top of the stack. Then, it invokes the takeinput function, its exec. context is created and and other functions context will not be created and placed in the stack until the takeinput context is popped out from the execution stack.
So, the correct order will be takeinput, processinput and outputinput.
I hope it answers your question.
JavaScript is not, generally asynchronous, but it does have asynchronous and event driven methods.
Ajax calls are the big asynchronous methods.
For events, I'm not sure that you can be guaranteed about an order of execution, but I might be wrong about that.
No, not by default/as standard, though there are asynchronous methods. And jQuery makes use of asynchronous behaviour much more so. But in each case, it's subjective, and can't be said that "All of the JavaScript is this or that".
Methods are always executed in the order they are called; the asynchronousness of them means that any may complete before another, even if called afterwards.
Javascript is a single-threaded beast, so strictly speaking tasks are not asynchronous as one might think of in terms of spawning child threads to execute code. The mechanisms that provide this create the illusion of asynchronicity, but its still single-threaded.

What happens in JavaScript when an AJAX call returns while the script is executing?

Suppose I write some JavaScript that performs an AJAX call with myCallback as a callback method to execute when the AJAX succeeds.
Suppose then that some other JavaScript method called myFunction is being invoked on my page when myCallback is invoked asynchronously.
Does one operation take precedence over the other? Do they both run at the same time? What happens?
Suppose then that some other JavaScript method called myFunction is being invoked on my page when myCallback is invoked asynchronously.
Does one operation take precedence over the other? Do they both run at the same time? What happens?
JavaScript on browsers is single-threaded (barring your using web workers, and the syntax for that is explicit). So myFunction will run until it returns — with certain caveats (keep reading). If the ajax layer completes an operation while myFunction is running (which it very well may) and needs to invoke the callback, that call gets queued. The next time your code yields, the next call in the queue will be triggered.
It might seem, then, that we never have to worry about race conditions. That's mostly true, but there are subtleties. For instance, consider this code:
var img = document.createElement('img');
img.src = /* ...the URL of the image... */;
img.onload = function() {
// Handle the fact the image loaded
foo();
};
doSomethingElse();
doYetAnotherThing();
Since JavaScript on browsers is single-threaded, I'm guaranteed to get the load event when the image loads, right?
Wrong.
The JavaScript code is single-threaded, but the rest of the environment probably isn't. So it can happen that, having set the img.src, the browser may see that it has a cached copy of the image it can use, and so it triggers the load event on the img between the img.src = ... line and the img.onload = ... line. Since my handler isn't attached yet, I don't get the call, because by the time I've attached my handler, the event has already fired.
But you can see the effect of queuing if we reverse those lines:
var img = document.createElement('img');
img.onload = function() {
// Handle the fact the image loaded
foo();
};
img.src = /* ...the URL of the image... */;
doSomethingElse();
doYetAnotherThing();
Now I'm hooking the event before setting src. If the event fires between the img.src = ... line and the doSomethingElse line (because the browser has the image in cache), the callback to my handler gets queued. doSomethingElse and doYetAnotherThing run before my handler does. Only when control passes out of my code does the queued call to my handler finally get run. The JavaScript code is single-threaded, but the environment is not.
You can also yield to the host environment in non-obvious ways. For instance, by calling alert or its breathren confirm, prompt, etc. These functions stick out like the sore thumbs they are in modern JavaScript because they aren't event driven; instead, JavaScript execution is suspended while a modal window is shown. But as bobince points out in his in-depth discussion here, that doesn't mean none of your other code will run while that modal is showing. It's still single-threaded, but the one thread is being suspended in one place (by the modal) and used to run code elsewhere in the meantime; a very fine distinction indeed. (Bob also points to some event handling — his focus example — that seems to break this rule, but it doesn't. His example calls focus, which in turn calls the event handlers, and then returns; no different from you calling your own functions.) The key thing the items that Bob points out have in common is that your code has called into something in the host environment that does goes away and does something (shows a modal dialog, fires blur and focus handlers, etc.).
(alert and its breathren in particular cause all sorts of nastiness, particularly around focus and blur, and I recommend avoiding them in favor of more modern techniques (which can also look about 18x better).)
So those are the caveats mentioned at the outset of the answer. And in particular, if myFunction calls alert, at least on Firefox the ajax completion callback will get run during the alert (it won't on most other browsers). If you're curious to try out what does and doesn't happen during alerts and such, here's a test page testing setTimeout and ajax; you could extend the tests to go further.
These answers are all wrong [edit: at least 3-4 wrong when this answer was posted]. The XHR event is put in the event queue/pool. When the single-threaded javascript thread is not busy, it will grab the next events from the event pool, and act on them. One of those events will be your XHR "AJAX" request, which will trigger the callback, which will then execute. This is how all event-driven systems without interrupts work.
edit: Upvoting Joe's answer which links to Is JavaScript guaranteed to be single-threaded? and mentions the subtle edge-cases. Very informative.
Javascript kind of single threaded see Is JavaScript guaranteed to be single-threaded?. So the answer is NO, your event handler and your function could run at the same time, or they might not.
The AJAX callback runs on the next event loop.
The ajax calls with be simultaneously. So when the ajax call is successful, the callback function is invoked which in turn invokes the the myfunction.
You could quickly test this by putting an alert('first one'); alert('second one'); in both functions, and see which modal popup comes up first. If your code really is affected by the order, put some conditional checks in both to prevent / allow something. The speed of native js vs the speed of a full round-trip to and from the server is wildly different. Unless you have some javascript running in an infinite loop, the odds of the ajax call returning during your other function execution is tiny.
AJAX calls are "asyncronous" which means "fire off a call and let me know what you want me to call back when im done".
so in short:
function DoSomething() { AJAXCall(Callback); }
... some time passes then ...
function Callback() { Done(); }
Between those 2 function calls anything can happen, the callback will still be called when the response comes back because although the javascript runtime is single threaded the browser will stack calls to happen in some sort of order (likely the order they are made but not garanteed).
It's a shame i just pulled done my old website because i had classic example of a page making several ajax calls on load, as each call came back it would populate various portions of the page.
although each call was "attached" to the document loaded event only 1 call could be made at a time but the server could respond to any call in any order because the server could be multithreaded (and likely is).
Think of javascript as being a virtual box in which which the browser can pass a small lump of code, it can only run 1 lump at a time but it can run lots of scripts in whatever order it sees fit (generally this is unpredictable with multiple ajax calls because who knows when the server might come back with a result)
When the ajax succeeds and invokes myCallback, it will run synchronously. So myCallback is like other functions, you call it first it will run first or you call it last it will run last. THEY WILL NOT RUN AT THE SAME TIME.

Categories

Resources