Asynchronous JavaScript

Doing multiple things at once is something we expect from modern applications. We expect our web browser to be able to download and show a video while we're somewhere else interacting with other elements. We expect web sites, software and applications to behave in an asynchronous way where two or more events can happen at the same time.

JavaScript is famously single-threaded, which means that it can only execute one code chunk at the same time. But we can still create good fluid experiences by using features like promises and asynchronous functions. These features leverage JavaScript's event loop and makes it easy to write applications that react to certain events.

Code example: synchronous

const fn = () => {
let x = "middle"
console.log("start")
console.log(x)
console.log("finished")
}
fn()
// "start"
// "middle"
// "finished"

This function and execution behaves as expected as we've written completely synchronous code where while one operation is being processes, nothing else can happen.

Code example: asynchronous

const fn = () => {
let x = "middle"
console.log("start")
setTimeout(() => console.log(x))
console.log("finished")
}
fn()
// "start"
// "finished"
// "middle"

Here we use the setTimeout function that takes an asynchronous callback function and an optional delay. We have not specified a delay and it will then default to zero. How come finished is logged before middle then?

The setTimeout function's trigger in the event loop queue is a timing event. When we execute the function called fn in the example it runs the various statements and declarations from top to bottom as always. When setTimeout is executed it is inserted into the event loop queue, and it is then handed over to the event loop system which is a separate system, and the function execution itself can continue on to the next statement. setTimeout's callback function will get executed first when the specified minimum delay has been reached and all events before it has been executed.