ES6: Promises

10min read

ES6 Promises – I will promise you love them.

Javascript Promises arrived natively with ES6 and are essentially a simpler way of dealing with asynchronous (async) operations in comparison to traditional callback-based approaches (ES5). They also provide us with a solid error handling simliar to try/ catch and bring a few helpful methods to manage multiple Promises simultaneously.

Typical async operations which Promises can be used for include API calls, DB queries aswell as reading and downloading files.

An ES6 Promise much like a promise in real life can have three possible states:

  • Pending – the promise’s outcome hasn’t yet been determined, because the asynchronous operation that will produce its result hasn’t completed yet.
  • Fulfilled – the asynchronous operation has completed, and the promise has a value.
  • Rejected – the asynchronous operation failed, and the promise will never be fulfilled. In the rejected state, a promise has a reason that indicates why the operation failed.

Promises are created via the new keyword and take in a function with two arguments resolve and reject. Resolve and reject are essentially methods which return whatever value we pass it. The Promise itself can be chained with a then() and a catch() method which each take a function with one argument. If the Promise gets fullfilled the then() method gets called and the value of resolve() gets passed to the then() method and can be used for any kind of operation. If the Promise gets rejected the catch() method runs with the value (reason) from rejected().

Lets see that in action. The setTimeout function represents in this simplified example an async operation like an API call, which returns successfull after 2 seconds (fullfilled) and calls the resolve() method with the value ‘Win’. ‘Win’ gets passed to the then() method and console.log() outputs it to the console.

Chaining Promises

Promises can be chained to one another via the then() method and subsequently pass the previously processed value to the next Promise in chain. This works only because both the then() and the catch() method return itself a new Promise.

Lets create a celebrate function which gets called after the sprinter Promise successfully resolved. It takes one argument (the value state which is returned from the sprinter Promise) and returns a resolved Promise with the value of the variable msg. Now we chain to the resolved Promise from the celebrate function an anonymus function that simply logs msg.

Handling Multiple Promises

Promises have additionally to resolve() and reject() two more built-in methods all() and race().

Promise.all()

The Promise.all() method takes in an array of multiple promisses and only resolves when all promises are fullfilled. Lets create three different sprinters, which take each a different time to resolve (3 seconds, 2seconds, 1 seconds). The Promise.all() method fires only after 3s when alle Promises are fullfilled.

Promise.race()

The Promise.race() method also takes in an array of multiple promisses and will resolve as soon as the first promise fullfills. The Promise.race() method called on the same three sprinters from the previous example this time will resolve already after 1 seconds (the fastest), because this is when the first sprinter (sprinter3) finishes.

Promises are async

Promises are not only used for async operations but they are async themselves. Meaning: Any synchronous code which is run before or after the Promise will run first before the Promise resolves or rejects. Lets prove it by creating a very simple Promise that resolves without any delay and console.log(‘middle’). Before the Promise we console.log(‘start’) and after the Promise we will console.log(‘end’).

Both the ‘start’ and ‘end’ console.log() statements get evaluated first because they run synchronous opposed to the async Promise.

Fetch and Promises

Most developers probably already used Promises without being aware of it. The Fetch API, a simple way to make network requests (similar to XMLHttpRequest or jQuery’s Ajax), infact returns a Promise.

In the following example we make an API call to a random joke API via fetch which resolves when the server responds with a status somewhere within the 2xx range and provides us with the joke in JSON format. If the Promise gets resolved the then() method gets called and the json is being parsed to an object. Since the json() method returns a Promise itself we can chain it with another then() and log the joke to the console.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *