← JavaScript

Asincronía

¿Qué son `async` y `await`, y qué ventaja tienen sobre las promesas con `.then()`?

Ver respuesta — intenta responderla en voz alta primero

async/await es una sintaxis para trabajar con promesas de una forma que se parece al código síncrono. await pausa la función hasta que la promesa se resuelve. Los errores se manejan con try/catch. La ventaja es que el código es más legible y fácil de seguir.

  • async: va antes de una función. Hace que la función siempre devuelva una promesa.
  • await: se usa dentro de una función async. Espera a que una promesa se resuelva y devuelve su valor, sin bloquear el hilo principal.

Es "azúcar sintáctico" sobre las promesas: por debajo siguen existiendo promesas, pero el código se lee de arriba hacia abajo, como si fuera síncrono. Los errores, que con .then() se capturan con .catch(), aquí se manejan con try/catch.

// Una función que devuelve una promesa
function obtenerUsuario() {
  return new Promise((resolve) => {
    setTimeout(() => resolve({ nombre: "Mike" }), 500);
  });
}

// Con async/await (legible, de arriba hacia abajo)
async function mostrarUsuario() {
  try {
    console.log("Cargando...");
    const usuario = await obtenerUsuario(); // espera aquí
    console.log(usuario.nombre); // "Mike"
  } catch (error) {
    console.log("Error:", error);
  }
}
mostrarUsuario();

// Comparación: lo mismo con .then()
function mostrarConThen() {
  console.log("Cargando...");
  obtenerUsuario()
    .then((usuario) => console.log(usuario.nombre))
    .catch((error) => console.log("Error:", error));
}

// Una función async siempre devuelve una promesa
async function saludar() {
  return "Hola";
}
saludar().then((mensaje) => console.log(mensaje)); // "Hola"
  • Usar await fuera de una función async (lanza un error, excepto en el nivel superior de los módulos modernos).
  • Olvidar el try/catch y dejar errores sin manejar.
  • Poner await en un bucle de forma secuencial cuando las tareas podrían ejecutarse en paralelo. Si son independientes, es mejor usar await Promise.all([...]).

"async/await es una forma más legible de trabajar con promesas. Marco la función como async, y con await espero a que una promesa se resuelva, obteniendo su valor directamente, sin encadenar .then(). Por debajo siguen siendo promesas, así que una función async siempre devuelve una promesa. Los errores los manejo con try/catch. La gran ventaja es que el código se lee de arriba hacia abajo como si fuera síncrono, lo cual es más fácil de seguir que muchos .then() encadenados."

Reto rápido

¿En qué orden imprime esto?

async function prueba() {
  console.log("1");
  await Promise.resolve();
  console.log("2");
}
console.log("0");
prueba();
console.log("3");
Ver respuesta

0, 1, 3, 2. Primero se imprime 0, luego se llama a prueba() y se imprime 1. Al llegar al await, la función se pausa y cede el control, así que se imprime 3. Finalmente, lo que viene después del await (2) se ejecuta como una microtarea.