One of Javascript's most powerful and interesting features is that it's asynchronous by design. Functions appear to run at the same time. This can be a bit confusing if you've come to Javascript development from a language that is inherently synchronous such as PHP, but it's useful and well worth learning.
When a Javascript engine runs code it organises it in to separate blocks. Each block is what's known as a scope - a function is a scope, a class is a block, a closure is a block, and so on. A piece of code that creates a new block, by calling a function for example, is the parent of that block, and it passes the variables in it's scope to it's new child.
On every process tick each code block runs and performs an action, so code blocks can run at the same time. This is what gives Javascript it's asynchronicity, and in turn it's apparent speed. Javascript isn't as fast as other languages because the process of running every block of code happens on a single thread, so it's really just multiplexing between lots of things rather than actually running two things at once. In a multi-threaded language there can be proper concurrency that makes things even faster, but generally that's not how the web works (yet).
The implication of this way of working is that when you write some code and run it, your code blocks can effectively run at the same time when a function is called before another finishes. For example;
{ //An operation that runs in a new block and takes some time, such as a network request console;}console;;console;
If this script was PHP the outer code block would stop running until the function returns. You'd see the output as;
output 1output 2output 3
The asynchronous nature of Javascript script means that the outer block won't stop while the asynchronousOperationThatTakesAWhile() function is running. This means the output will be;
output 1output 3output 2
This might be confusing but it's very useful if you code often has to wait for operations to complete. In web development that happens a lot becayse you're often waiting for network calls. You wouldn't want animations to halt and pages to become unresponsive just because your code has submitted an XMLHttpRequest. Asynchronous code is great.
There are two common patterns to make writing asynchronous code easier. The first is by providing a callback to the code that runs asynchronously. Going back to our example, the solution using a callback might look like;
{ console; ;}console;;
Now the output would be in the right order because the callback function that displays output 3
is run after the network operation and the second output.
Callbacks are a good solution for very simple code, but they become unweildy if we need to nest calls several layers deep, or if we need to run some code after several asynchronous operations have completed. Managing multiple callbacks and having them execute in order is a hard problem.
The second pattern is far better. Javascript has a feature called promises that can make managing asynchronicity much easier.
A promise is a variable that will be populated later. Promises include features that can wait until the value is resolved (populated with a value) or rejected (an error occurred) and only then run a callback. This gives us much better control over the order in which our code runs.
{ var promise = { console; ; }; return promise;}console;var promise = ;promise
This code is longer, and might appear to actually be more complicated than the callback code to start with, but it's not as bad as it looks and once you understand it there's a number of big advantages over the callback style.
If you want to understand promises better there's a great tutorial on Google: https://developers.google.com/web/fundamentals/getting-started/primers/promises
While Javascript has native promises there is a new feature that isn't native yet but is still worthwhile understanding: observables. A promise is a variable that will be populated in the future, and an observable is the array equivalent - it's an array that will be populated asynchronously, so it could have values added in to it at any time. Observables are a good way of managing lists of things that are filled by network requests; using an observable means we don't need to wait until every request has completed before we start to use it, so our code gets an apparent speed boost from the perspective of the user.
The difficulty with asynchronous code when we come to write tests is making sure our test code waits for our application code to complete before trying to assert something. If our application calls an asynchronous function without using a promise then it'll return before that function has completed its work, and the test will continue before we want it to. This can be problematic, and fixing it isn't really part of changing our tests. We need to change the way we write our code. This is where promises shine.
Most test frameworks include functionality to wait for the application code in the browser to complete. This is done behind the scenes by spying on the code to see what it's doing, and to see when it completes.
Fortunately in the case of some frameworks the code for the tests themselves is absolutely identical regardless of what's happening behind the scenes to deal with the asynchronous nature of the application. Jasmine will automatically wait for a promise to be resolved or rejected. Karma will too, but in some cases we need to give it a nudge. For example, $httpbackend won't automatically resolve a mocked API call without calling $httpbackend.flush() during the test.