Not all lines of code run asynchronously in Javascript. It depends on your code. For example:
var someFunc = function () {
if (something) {
console.log('something');
}
if (somethingElse) {
console.log('something else');
}
};
Will always write the following output:
something
something else
However if instead of printing the values you are calling a function that will be run later (like an Ajax request or a setTimeout callback), there is no guarantee that your code is run in the exact order. This behaviour depends on the function you are calling. For example the JQuery $.get()
function is asynchronous (which means it will call your function at a later time that is not in your control) like this:
var someFunc = function () {
if (something) {
$.get('some-file.txt').done(function (result) {
console.log(result);
});
}
if (somethingElse) {
$.get('some-other-file.txt').done(function (result) {
console.log(result);
});
}
};
The resulting output can be the contents of 'some-file.txt' and 'some-other-file.txt' in any other.
As a rule of thumb whenever you are passing a function to another function (callbacks) you may be using the asynchronous feature of Javascript.
Nested callbacks
One way to solve this issue is to call the second asynchronous call in the first function:
var someFunc = function () {
if (something) {
$.get('some-file.txt').done(function (result1) {
console.log(result1);
if (somethingElse) {
$.get('some-other-file.txt').done(function (result2) {
console.log(result2);
});
}
});
}
};
But as you might have guessed this code will be hard to read.
Promises to the rescue
With Promises you can have a code that is easier to read.
Let's write the above ugly code with promises:
var someFunc = function () {
if (something) {
$.get('some-file.txt').then(function (result1) {
console.log(result1);
if (somethingElse) {
return $.get('some-other-file.txt');
}
}).then(function (result2) {
console.log(result2);
});
};
In general, promises make the code more readable and avoid too many nested callbacks. You can chain promises and it will read like synchronous code but it actually runs asynchronously.
See these questions to get more information:
What's the catch with promises?
- They are not supported in old browsers (but you can add them with a 3rd party library like ES6 Promise Polyfill.
- Before the promises were officially standardized every library had their own implementation which are slightly incompatible (jQuery, Angular, Ember)
- They are a new concept to learn so the learning curve will be a little steep for newcomers.