Promise and async/await

Promise and async/await

Today, it will shortly. Consider Promise class and async/await keywords use cases. Which one of them is a better option? Would the choice better in each situation?

The Promise

Promise class is standard ECMA Script version 6 (shorter: ES6) feature. It’s a fantastic way to avoid callback hell and it’s supported by each modern browser out of box.

Promise is very powerful tool for parallel tasks. It supports convenient waiting for finish of all tasks and first completion too. Take a look to sample code:

/**
 * @private
 * @param {number} seconds
 * @param {string} result
 * @returns {Promise<string>}
 */
const task = (seconds, result) => new Promise((resolve => setTimeout(() => resolve(result), seconds * 1000)));

Promise.all([
  task(1, 'A'),
  task(3, 'B'),
]).then(results => console.log('Promise: all', results));
Promise.race([
  task(2, 'A'),
  task(0.5, 'B'),
]).then(results => console.log('Promise: 1st race', results));
Promise.race([
  task(1, 'A'),
  task(3, 'B'),
]).then(results => console.log('Promise: 2nd race', results));

It will produce the following output:

Promise: 1st race B
Promise: 2nd race A
Promise: all [ 'A', 'B' ]

But sequential (asynchronous) tasks implementations is often hard to read. Consider the easiest sample, API data fetching:

fetch('https://bitbay.net/API/Public/KZCPLN/trades.json', {
  method: 'GET',
  headers: {
    Accept: 'application/json',
  },
}).then(response => response.json())
  .then(json => json.reduce((accumulator, item) => accumulator + item.price * item.amount, 0))
  .then(sum => console.log('sum:', sum.toFixed(2)))
  .catch(e => console.error('Fetch issue:', e));

So to execute sequential operations, async/await keywords would much better option.

Await for Async

When you wish to use await keyword, you must know one thing now – await works inside async function block only.

/**
 * @private
 * @param {string} url
 * @param {object} options
 * @returns {Promise<Response>}
 */
const fetchAsync = async(url, options) => fetch(url, options);

/**
 * @private
 * @returns {Promise<void>}
 */
async function printSumAsync() {
  const response = await fetchAsync('https://bitbay.net/API/Public/KZCPLN/trades.json', {
    method: 'GET',
    headers: {
      Accept: 'application/json',
    },
  });
  const json = await response.json();
  const sum = json.reduce((accumulator, item) => accumulator + item.price * item.amount, 0);
  console.log('async sum KZC/PLN', sum.toFixed(2));
}

Mix Await and Promise to Async

In fact, async function always returns the Promise object that can be resolved or rejected to the value. So technically, async/await keywords are pretty syntax sugar for Promise objects.

printSumAsync().then(() => console.log('async as promise')).catch(e => console.error('async promise error:', e));

If you use asynchronous function which returns void result, you mustn’t use await keywords. And finally, you can call async function from synchronous code!

try {
  printSumAsync();
} catch (e) {
  console.error('Async fetch issue:', e);
}

That’s all for now. It’s nice knowledge to start writing asynchronous code in JS. See you again.

Post a comment