Starting with the definition:
Asynchrony, in computer programming, refers to the occurrence of events independently of the main program flow and ways to deal with such events. These may be "outside" events such as the arrival of signals, or actions instigated by a program that take place concurrently with program execution, without the program blocking to wait for results.
-- Davies, Alex (2012). Async in C# 5.0, via Wikipedia on Asynchrony (computer programming)
In case of JavaScript, it works like this (simplified): There is a queue of tasks waiting to be executed by the main (and only) thread. When you load a script, it is a task placed on this queue. A task runs until it exits, and no other task can interrupt it. However, a task can cause other tasks to be placed on the queue. When one task finishes, the next task on the queue starts. If the queue is empty, the first task that enters the queue afterwards gets immediately executed.
The main ways for tasks to enter the queue, besides being the main task of script being parsed and executed: triggering an event will place handlers registered for that event on the task queue, and reaching a time scheduled by setTimeout
or setInterval
will place the associated task on the task queue.
In JavaScript context, everything that executes within the same task ("main program flow") is said to be synchronous. Everything that is executed in a future task is called asynchronous. Another way to tell is - if the next statement executes before the callback, it is asynchronous; if the next statement executes after the callback, it is synchronous.
$.get(opts, callback)
is an asynchronous call, because the task that executes the function callback
will be placed on the task queue when triggered by the onreadystatechange
event. If you have a statement following it, it will get executed first; it is only after that task finishes, that the task which entered the task queue because of an update to your AJAX call will have a chance to run.
In contrast, $.each(collection, callback)
is a synchronous call, because callback
will be directly called from the each
function, without exiting the current task, and will not generate any additional tasks (not by itself anyway, callback
of course can generate additional tasks). The next statement will have to wait until each
finishes iterating over every element of collection
.
Note that promises are simply wrappers over this mechanism. Everything you can do with promises, you can do without them, just the code will not be as pretty and legible.