The callback pattern on the web

The way to go about it is to attach functions to future events. When the event occurs, our attached function gets executed. An example of this is XMLHttpRequest, which looks like this:

const xhr = new XMLHttpRequest();
xhr.open('GET','/path', true);
xhr.onload = () => {
// run me when the request is finished
}

xhr.send(null);

What we can see here is that all lines are executed synchronously except for xhr.onload. Attaching the function to onload happens synchronously, but running the function that onload is pointing to doesn't happen until the request finishes. We can also define other events, such as onreadystatechange , and attach a function to that as well:

xhr.onreadystatechange = () => {}

As the web is single-threaded, this is how we deal with asynchronous code. The onreadystatechange object and its callback are registered with the operating system. Once the asynchronous part has been completed the operating system is woken up by an event being dispatched. Thereafter, the callback is invoked.