Rather than throwing code at you, there are two concepts that are key to understanding how JavaScript handles callbacks and asynchronicity (is that even a word?)
The Event Loop and Concurrency Model
There are three things you need to be aware of; The queue; the event loop and the stack
In broad, simplistic terms, the event loop is like the project manager, it is constantly listening for any functions that want to run and communicates between the queue and the stack.
while (queue.waitForMessage()) { queue.processNextMessage();}
Once it receives a message to run something it adds it to the queue. The queue is the list of things that are waiting to execute (like your AJAX request). imagine it like this:
- call foo.com/api/bar using foobarFunc
- Go perform an infinite loop... and so on
When one of these messages is going to execute it pops the message from the queue and creates a stack, the stack is everything JavaScript needs to execute to perform the instruction in the message. So in our example it's being told to call foobarFunc
function foobarFunc (var) { console.log(anotherFunction(var));}
So anything that foobarFunc needs to execute (in our case anotherFunction
) will get pushed onto the stack. executed, and then forgotten about - the event loop will then move onto the next thing in the queue (or listen for messages)
The key thing here is the order of execution. That is
WHEN is something going to run
When you make a call using AJAX to an external party or run any asynchronous code (a setTimeout for example), JavaScript is dependant upon a response before it can proceed.
The big question is when will it get the response? The answer is we don't know - so the event loop is waiting for that message to say "hey run me". If JavaScript just waited around for that message synchronously your app would freeze and it will suck. So JavaScript carries on executing the next item in the queue whilst waiting for the message to get added back to the queue.
That's why with asynchronous functionality we use things called callbacks. - A function or handler that, when passed into another function, will be executed at a later date. A promise uses callbacks (functions passed to .then()
for example) as a way to reason about this asynchronous behaviour in a more linear way. The promise is a way of saying "I promise to return something at some point" and the callback is how we handle that value that is eventually returned. jQuery uses specific callbacks called deffered.done
deffered.fail
and deffered.always
(amongst others). You can see them all here
So what you need to do is pass a function that is promised to execute at some point with data that is passed to it.
Because a callback is not executed immediately but at a later time it's important to pass the reference to the function not it executed. so
function foo(bla) { console.log(bla)}
so most of the time (but not always) you'll pass foo
not foo()
Hopefully that will make some sense. When you encounter things like this that seem confusing - i highly recommend reading the documentation fully to at least get an understanding of it. It will make you a much better developer.