javascript-async-y-await

Async and await in JavaScript

  • 4 min

In JavaScript, async and await are a syntax for writing asynchronous code that is simpler easier to read and maintain than previous alternatives (like callbacks and promises)

Introduced in ECMAScript 2017, async/await allows us to write code sequentially, instead of nesting callbacks or chaining promises.

Internally, async/await is based on promises. In fact, then/catch and async/await are functionally equivalent.

But async/await provides a more convenient syntax to use, than nesting promises (it’s syntactic sugar to make our lives easier).

Another advantage of async/await is that it handles errors in a simpler way. With async/await, you can use the try/catch structure (which is more familiar and easier to understand for developers).

async/await Syntax

The async/await syntax is based on two keywords,

  • async is placed before a function to indicate that it contains asynchronous code.
  • await is placed before any operation that returns a promise to indicate that the code must wait for the promise to resolve before continuing.

Async

The async keyword is used to declare an asynchronous function. A function marked with async always returns a promise.

  • If the function returns a value, the promise is resolved with that value.
  • If the function throws an exception, the promise is rejected with that exception.
async function miFuncion() {
  return 'Hola, mundo';
}

miFuncion().then(console.log); // 'Hola, mundo'
Copied!

In the previous example, miFuncion is an asynchronous function that returns a promise resolved with the value 'Hola, mundo'.

Await

The await keyword is used inside an async function to wait for a promise to resolve.

await pauses the execution of the async function until the promise is resolved or rejected.

async function miFuncion() {
  let valor = await Promise.resolve('Hola, mundo');
  console.log(valor); // 'Hola, mundo'
}

miFuncion();
Copied!

In this example, await is used to wait for the promise to resolve, and then the resulting value is printed.

Basic Example

Let’s see it with a simple example,

async function obtenerDatos() {
  //function that simulates returning a promise
  const respuesta = await FuncionQueDevuelvePromesa();

  console.log(respuesta);
}
Copied!

In this example,

  • The obtenerDatos function is asynchronous
  • FuncionQueDevuelvePromesa is a function that simulates returning a promise (it’s the response from a network request).
  • We use the await keyword to wait for a promise to resolve before continuing with the next line of code.
  • After the promise is resolved, we can do whatever we want with respuesta.

This would be equivalent to this code, without using async and await

function obtenerDatos() {
  // Call the function that returns a promise
  FuncionQueDevuelvePromesa()
    .then((respuesta) => {
      // Handle the response when the promise resolves
      console.log(respuesta);
    })
    .catch((error) => {
      // Handle errors if the promise is rejected
      console.error(error);
    });
}
Copied!

Which as we can see is quite a bit more of a pain 😅

Handling Errors

To handle errors in async functions, you can use try/catch instead of .catch() as you would with promises.

async function obtenerDatos() {
  try {
    let respuesta = await fetch('https://api.example.com/data');
    if (!respuesta.ok) {
      throw new Error('Error en la respuesta de la red');
    }
    let datos = await respuesta.json();
    console.log(datos);
  } catch (error) {
    console.error('Error:', error);
  }
}

obtenerDatos();
Copied!

In this example, if an error occurs at any point inside the try block, the flow of control passes to the catch block, where the error is handled.