Escribir código asíncrono en JavaScript dejó de ser complicado gracias a async await. Esta sintaxis, construida sobre promesas, permite leer operaciones asíncronas como si fueran síncronas, manteniendo toda la potencia del event loop y los mecanismos que ya conoces. Entender que se trata de azúcar sintáctica (syntactic sugar) sobre las promesas es la clave para dominarla por completo.
¿Qué hace la palabra clave async en una función?
Colocar async antes de cualquier declaración de función produce dos efectos inmediatos [0:22]:
- Marca la función como asíncrona.
- Hace que siempre devuelva una promesa, sin importar qué valor retornes dentro de ella.
Una función tradicional que retorna un string entrega ese valor directamente. En cambio, una función declarada con async envuelve automáticamente el retorno en Promise.resolve() [1:08].
javascript
async function saludoAsync() {
return "hola async";
}
console.log(saludoAsync()); // Promise { 'hola async' }
Aunque retornes "hola async", lo que obtienes al invocarla es una promesa resuelta con ese valor.
¿Cómo funciona await y por qué no bloquea el hilo principal?
El verdadero poder está en await [1:18]. Solo puede usarse dentro de funciones async y lo que hace es pausar la ejecución de esa función hasta que la promesa se resuelva, devolviendo el valor resuelto directamente a una variable.
¿Cuál es la diferencia entre promesas con .then y async await?
Con promesas encadenadas, accedes al resultado dentro de callbacks. Con await, el valor llega directamente a la variable, eliminando la necesidad de .then() [1:45].
javascript
// Con promesas
function obtenerUsuario() {
return fetch("https://fakeapi.platzi.com/users/2")
.then(response => {
if (!response.ok) throw new Error("Error");
return response.json();
});
}
// Con async await
async function obtenerUsuarioAsync() {
const response = await fetch("https://fakeapi.platzi.com/users/2");
if (!response.ok) throw new Error("Error");
return response.json();
}
const usuario = await obtenerUsuarioAsync();
console.log(usuario); // { name: "María" ... }
El código con async await es más legible y mantiene la convención de errores primero (error first) [2:37]. Cada await pausa la función hasta que la promesa específica se resuelva: el primero espera la respuesta HTTP y el segundo parsea el JSON [2:52].
Un punto fundamental: await no bloquea el hilo principal [3:28]. Pausa únicamente la función async donde se encuentra, mientras el resto del programa sigue ejecutándose con normalidad.
¿En qué formas de función se puede usar async?
async funciona con cualquier sintaxis de función en JavaScript [3:40]:
- Declaración de función:
async function cargar() { ... }.
- Expresión de función:
const cargar = async function() { ... }.
- Arrow function:
const cargar = async () => { ... }.
- Método de objeto:
const api = { async obtener() { ... } }.
- Método de clase:
class Servicio { async obtener() { ... } }.
¿Cuáles son las cuatro reglas clave de async await?
Antes de usar esta sintaxis en cualquier proyecto, es necesario recordar estas reglas [4:38]:
await solo funciona con promesas.
- Si la promesa se rechaza,
await lanza un error.
- Solo puede usarse dentro de funciones
async.
- Async await no reemplaza las promesas, es azúcar sintáctico sobre ellas.
Estas reglas refuerzan que no se trata de un mecanismo nuevo, sino de una capa de legibilidad sobre lo que las promesas ya ofrecen. El código asíncrono se lee como síncrono sin perder ninguna funcionalidad.
Queda una pregunta abierta: ¿qué sucede cuando la promesa que estamos esperando se rechaza y cómo se manejan los errores con esta sintaxis? Comparte en los comentarios cómo convertirías un fetch con .then() a async await, o cómo crearías funciones con las cuatro formas de declaración para consumir una API como JSONPlaceholder.