La sintaxis JavaScript de flujo asíncrono async
/await
lleva ya cosa de un año funcionando en la práctica totalidad de los navegadores modernos. El infiernos de los callbacks pronto será cosa del pasado.
Eso sí, Internet Explorer no es, ni será nunca, compatible. Para IE, la única opción sería usar un transpilador, como Babel.
Sintaxis
Las funciones declaradas async
se denominan funciones asíncronas. Su contenido puede ser como el de cualquier otra función. La diferencia es que siempre devuelven implícitamente una promesa, que será:
- resuelta (resolved) con el valor que devuelva la función (
return
), o bien - rechazada (rejected) con la excepción, no capturada, que se lance durante la ejecución de la función.

Promise
de manera transparente.
Operador await
Existe una tercera opción, que sería dejar la promesa pendiente de resolución (pending). Para eso está el operador await
.
Supongamos que tenemos una función descargarFicheros()
que realiza alguna tarea asíncronamente y devuelve una promesa (podría estar implementada con la sintaxis async
/await
, pero no necesariamente). Podríamos usarla dentro de una función asíncrona de la siguiente manera:
async function miFuncionAsincrona() {
try {
let ficheros = await descargarFicheros();
// Hacer cosas interesantes con los ficheros...
} catch (error) {
console.error(error);
}
}
Al invocar esta función, ocurriría lo siguiente:
- Al llegar a la expresión con await se ejecuta la función
descargarFicheros
y se detiene la ejecución de la funciónmiFuncionAsincrona
en ese punto. - Se pasa el control a la función que la invocó, devolviendo una promesa pendiente de resolución.
- Cuando se resuelve la promesa devuelta por
descargarFicheros
, se continúa con la ejecución de la función según proceda:- Si la promesa es resuelta, se asigna su valor a la variable
ficheros
y se continúa en la línea siguiente. - Si es rechazada, se pasa el control al bloque
catch
, asignando el valor del rechazo al identificadorerror
.
- Si la promesa es resuelta, se asigna su valor a la variable
Importante: el operador await
debe usarse siempre dentro de una función declarada async
, o el motor de JavaScript nos lo recordará con un inquietante error de sintaxis:
SyntaxError: await is only valid in async functions and async generators
SpiderMonkey
«Azúcar sintáctica»
La sintaxis async
/await
permite trabajar con promesas de una manera mucho más fácil de leer y de depurar. Por ejemplo, el siguiente código:
function miFuncion() {
obtenerDatos('--consulta--').then(obtenidos => {
// Hacer algo con los datos obtenidos
procesarDatos(obtenidos).then(procesados => {
// Hacer algo con los datos procesados
});
}).catch(error => {
// Tratamiento de errores
});
}
Con async
/await
quedaría así:
async function miFuncion() {
try {
let obtenidos = await obtenerDatos('--consulta--');
// Hacer algo con los datos obtenidos
let procesados = await procesarDatos(obtenidos);
// Hacer algo con los datos procesados
} catch (error) {
// Tratamiento de errores
}
}
Se diría que es código asíncrono escrito con «estilo síncrono», si ustedes me entienden. ¡Lo mejor de los dos mundos!
¿Puedes usarlo ya?
La siguiente tabla resume los entornos en los que ya es posible usar esta nueva sintaxis, y desde qué fecha y versión.
Promises | Async functions | |
---|---|---|
Google Chrome | Feb 2014 (33) | Dic 2016 (55) |
Apple Safari | Sep 2014 (7.1) | Mar 2017 (10.1) |
UC Browser | Ago 2016 (11.8) | Ago 2016 (11.8) |
Mozilla Firefox | Abr 2014 (29) | Mar 2017 (52)
|
Opera | Mar 2014 (20) | Dic 2016 (42) |
Internet Explorer | Incompatible | Incompatible |
Microsoft Edge | Jul 2015 (12) | Abr 2017 (15) |
Samsung Internet | Abr 2016 (4) | Oct 2017 (6.2) |
Android Browser | Jun 2014 (4.4.3) | May 2017 (67) |
Node.js | Sep 2015 (4) | Feb 2017 (7.6.0) |
Como ves, la cuenta atrás ya está en marcha. A no ser que tu aplicación necesite ser compatible con navegadores seriamente obsoletos, es muy posible que ya puedas empezar a beneficiarte de este nuevo avance de JavaScript.
¿Cómo lo ves? ¿Estás ya usando esta sintaxis? ¿Te ha supuesto un gran cambio? ¿Cuál es tu característica favorita de ES2015+?