Asynchronicity in JavaScript
Tags: javascript, callback, promise, await
Published: 2019-09-04 13:01:06

---
title: Asynchronicity in JavaScript
published: true
description: Examples about Callbacks, Promises, Async/Await.
tags: javascript, callback, promise, await
---

When things can happen independently of the programs main thread, we're talking about [asynchronicity](https://en.wikipedia.org/wiki/Asynchrony_(computer_programming)). By default JavaScript is a synchronous [single threaded](https://en.wikipedia.org/wiki/Thread_(computing)#Single_vs_multiprocessor_systems) language which means it cannot run multiple threads parallelly. Your code will be executed from top to bottom, one after another. But what if you need to do some heavy computation on client side or just to wait for a long server response? The UI freezes until it's done, no clicks, no scrolling, no animations.

JavaScript (as it's name suggests) is a [high-level](https://en.wikipedia.org/wiki/High-level_programming_language), [interpreted](https://en.wikipedia.org/wiki/Interpreted_language) [scripting language](https://en.wikipedia.org/wiki/Scripting_language) running in a browser by it's [engine](https://en.wikipedia.org/wiki/JavaScript_engine). For more information about engines, here is [Gecko](https://developer.mozilla.org/en-US/docs/Mozilla/Gecko)s and [V8](https://v8.dev/)s homepage. Browser provides features that can handle asynchron functionality. [Web API](https://developer.mozilla.org/en-US/docs/Web/API)s, the [event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop), the task queue are not part of the JavaScript engine. For deeper understanding of how event loop works check this great video.

{% youtube cCOL7MC4Pl0 %}

## Callbacks

A callback is a function which is passed to another function as a parameter. The simplest example for a callback is handling a button click. You need to listen for the click event, and when it happens, the browser will exectute the given function (the callback).

```javascript
const button = document.getElementById('button');
const myCallback = () => alert('Click happened');

button.addEventListener('click', myCallback);
```

This way you can handle asynchronous server requests as well.

```javascript
const request = new XMLHttpRequest();
const myCallback = event => console.log(event.target.response);

request.addEventListener('load', myCallback);
request.open('GET', 'http://www.example.org/example.txt');
request.send();
```

Callbacks are good for simple cases like handling a button click. The pain starts when you need to nest callbacks, and wrap logics into. It's called "Callback Hell" or "The Pyramid of Doom". For example let's wait for page load, then listen for the button click and when the button was cliked do a server request, then log it to the console.

```javascript
window.addEventListener('load', () => {
  document.getElementById('button').addEventListener('click', () => {
    const request = new XMLHttpRequest();
    request.addEventListener('load', (event) => {
      console.log(event.target.response);
    });
    request.open('GET', 'http://www.example.org/example.txt');
    request.send();
  });
});
```

## Promises

In ES6 there is a new feature called [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). It's an object representing the eventual completion or failure of an asynchronous operation. It's constructor waits an exectutor function with parameters "resolve" and "reject". You can use the "then" method as fulfillment and rejection handler, "catch" for handle only rejection and "finally" for run code when promise is done. For example let's wrap a timeout into promise.

```javascript
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello from promise');
  }, 2000);
});

myPromise.then(returnedValue => console.log(returnedValue));
```

Promises are handy when you need to nest asynchronous parts but want avoid the Callback Hell. In this example I'll use [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) which returns a Promise. Let's create a snippet with a timeout. After that do a server request and then log the data out.

```javascript
const timeout = () => new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello from promise');
  }, 2000);
});

const request = () => fetch('http://www.example.org/example.txt')

timeout()
  .then(request)
  .then(response => response.json())
  .then(data => console.log(data));
```

## Async/Await

ES7 brings [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) and [await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) syntax which are just syntactic sugar over Promises. "await" can only be used inside an async function. With them you can wait for promises with a very clear readable syntax. Let's refactor the code from above with async/await.

```javascript
const timeout = () => new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello from promise');
  }, 2000);
});
const request = async () =>
  await fetch('http://www.example.org/example.txt');

await timeout();
const request = await request();
console.log(request.json());
```