En mi escrito anterior hablé un poco por encima de que es el asincronismo de JavaScript y como esto nos afecta al ejecutar varias funciones a nuestro código, sin embargo por cuestiones prácticas dejamos mucho por fuera,
Cuando veíamos como se ejecutaba nuestro código concluimos que JavaScript es asíncrono, no bloqueante y concurrente (si quieres expandir más estos conceptos te dejo el enlace al escrito anterior "aquí").
Ahora tomaremos las 3 herramientas más importantes y los diseccionaremos para comprendedlos al máximo.
1) Callbacks
Son una función que se pasa como argumento de otra función, de forma que podamos llamarla más adelante para completar alguna tarea en donde la función principal será la encargada de hacer el llamado de nuestro callback (la función parámetro). Veamos un Ejemplo:
function Sumar(a, b, callback){
return callback(a+b);
}
Sumar(a, b, function(r){
console.log('El resultado es ' + r)
})
En este ejemplo cuando llamemos a nuestra función Sumar
y declaremos que va a recibir como parámetro la función, vamos a declarar la variable que va a ser retornada, dicha variable va a ser colocada dentro de la función r
, esta será impresa en pantalla.
La sintaxis de un callback es sencilla, y una función normal puede ser transformada a una función asíncrona al emplearlos. El resto de patrones asíncronos en Javascript está basado en callbacks de un modo u otro, es por ello que es necesario aprender el como funciona en su base antes de estudiar funciones más complejas.
Ejemplo de Callback Hell:
Hay casos donde tendremos podremos concatenar cualquier cantidad de Callbacks, a esto lo llamamos Callback Hell, esto dificulta la lectura del código, además de que puede hacer un bucle infinito, veamos un ejemplo para ilustrarlo mejor
setTimeout(function(){
console.log("Etapa 1 completada");
setTimeout(function(){
console.log("Etapa 2 completada");
setTimeout(function(){
console.log("Etapa 3 completada");
setTimeout(function(){
console.log("Etapa 4 completada");
// Podríamos continuar hasta el infinito...
}, 4000);
}, 3000);
}, 2000);
}, 1000);
En este caso, la función setTimeout hace que pasado 1,2,3 y 4 segundos te imprime un mensaje, pero como puede seguir tantas veces como estén concatenados los callbacks estén concatenados (también cabe destacar que un callback no estrictamente debe de llamarse callback, basta que sea una función cuyo argumento sea otra función).
Una forma de verificar si nuestro callback presenta errores es con
callback(err,data)
, esta suele devolver nulo la variable err
si no ha ocurrido ningún error, en caso contrario, existe un error en el Callback.
2) Promise
A partir de ECMAScript 6 se introducen las promesas a JavaScript, estas básicamente son funciones no-bloqueantes y asíncronas donde al procesarlas pueden retornar un valor de inmediato, en un futuro o nunca.
Imaginemos que tenemos un niño travieso, nosotros para que no moleste le prometemos que si se porta bien, le daremos un chocolate mañana, el niño busca de portarse mejor porque confía en la promesa que es el chocolate, sin tener la certeza de en que momento llegará el chocolate mañana o si verdaderamente llegará.
Ahora con código:
let completado = true;
const tareaCompletada = new Promise((resolve, reject) => {
if (completado) {
const trabajoCompletado = 'He completado la tarea';
resolve(trabajoCompletado);
} else {
const trabajoFallido = 'No he podido completar la tarea';
reject(trabajoFallido);
}
});
Ahora este ejemplo consiste en una función que evaluará el estado de la variable local completado
, esta procederá de ser true
o la promesa será rechazada de ser false
, la función entregará un String
de texto pero también podría realizar actividades más complejas como generar un objeto con ciertas caracteristicas o delegar a un Callback la ejecución.
3) Async / Await
Las funciones async
y la palabra clave await
, entre las nuevas especificaciones de EmacScript 2017, estas claves surgieron para simplificar el manejo de las promesas siendo una abstracción de alto nivel de las promesas de JavaScript con la particularidad de que pueden pausarse a sí mismas y continuar su ejecución en otro momento
En la práctica, este comportamiento es equivalente a decir que el operador await 'pausa la ejecución' o 'espera a una promesa', esto no quita que Async / Await siguen siendo funciones asíncronas y no bloqueantes.
Veamos un ejemplo:
async function obtenerDatos() {
return 'hola!';
}
La estructura básica consiste en colocar async
frente a una función para implementarla, podrás ver este resultado por la consola:
__proto__: Promise
[[PromiseStatus]]: "fulfilled"
[[PromiseValue]]: Object
De hecho, si inspeccionas el código, podrás comprobar que la promesa que es devuelta incluye las propiedades PromiseStatus
PromiseValue
. Para comprobarlo, ejecuta la función obtenerDatos
console.log(obtenerDatos());
Con el uso de await
en una función asíncrona, podremos ejecutar la promesa y obtener su resultado, esto nos permite pausar la ejecución de la función hasta que la promesa devuelva respuesta (dato o error).
async function obtenerUsuario() {
const response = await fetch();
const data = await response.json();
console.log(data);
}
obtenerUsuario();
El operador await que anteponemos a la función fetch en el interior de la función obtenerUsuario
evitará que la línea siguiente se ejecute hasta que no obtengamos un valor de vuelta. De este modo nos aseguramos de que la constante data no esté vacía. Como ves, no es necesario usar then, como sí hacemos con las promesas, para obtener el resultado
Con esto hemos visto un poco de como funcionan el asincronismo de JavaScript, si quieres profundizar de este tema, pásate por nuestro curso Mastering React.
Sin más, me retiro, hasta la próxima!!!
https://lemoncode.net/lemoncode-blog/2018/1/29/javascript-asincrono
http://panamahitek.com/introduccion-al-paradigma-de-la-programacion-asincrona/
https://https-bedu-org.gitbook.io/javascript-desde-cero/parte-6/asincronismo/que-es-asincronismo
https://medium.com/@sergiodxa/qué-son-y-cómo-funcionan-las-promesas-en-javascript-d4e541c646a6
https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Usar_promesas
https://www.neoguias.com/promesas-javascript/