Introducción a las promesas en JavaScript
Ya sabes que el uso del modelo de asincronía con callbacks fácilmente conduce a la situación del infierno de callbacks (callback hell). Por eso en JavaScript se introdujo un nuevo modelo llamado promesas (promise). Aprendamos este modelo.
Una promesa representa un objeto, al cual como parámetro se le pasa una función, dentro de la cual debemos colocar nuestro código asíncrono:
let promise = new Promise(function() {
// código asíncrono
});
Como ves, guardé el objeto con la promesa
en la variable promise. En algún otro
lugar del código puedo aplicar a esta variable
el método then, pasándole una función
con el código que debe ejecutarse al
completarse el código asíncrono, escrito
al crear esta promesa:
promise.then(function() {
// se ejecutará al completarse el código asíncrono
});
Suena confuso, así que veamos un ejemplo. Supongamos que tengo el siguiente código asíncrono:
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
Supongamos que quiero resolver para él nuestra tarea principal
de asincronía: ejecutar cierto
código después de que se active el temporizador. Además,
no quiero colocar este código dentro del propio temporizador
y quiero que el resultado,
escrito por mí en la variable result, llegue de alguna manera a este código.
En general, hemos resuelto esta tarea en lecciones anteriores
a través de callbacks y suscripciones. Veamos
ahora cómo hacerlo mediante promesas.
Primero necesitamos envolver nuestro código asíncrono en una promesa:
let promise = new Promise(function() {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Sin embargo, esto no es suficiente. Debemos indicar explícitamente que nuestro código asíncrono ha finalizado. Para ello nos ayudará una función de finalización especial, que llega automáticamente al primer parámetro de la función, si se especifica:
let promise = new Promise(function(resolve) { // indicamos el parámetro
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
}, 3000);
});
Usando la función de finalización podemos indicar explícitamente a la promesa que el código asíncrono ha finalizado. Para ello debemos llamar a esta función en el lugar que necesitemos:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(); // finalizamos la promesa
}, 3000);
});
Además, si queremos pasar al exterior algún resultado del código asíncrono, podemos pasarlo como parámetro a nuestra función de finalización:
let promise = new Promise(function(resolve) {
setTimeout(function() {
let result = [1, 2, 3, 4, 5];
resolve(result); // pasamos el resultado
}, 3000);
});
Por supuesto, se puede prescindir de la variable intermedia:
let promise = new Promise(function(resolve) {
setTimeout(function() {
resolve([1, 2, 3, 4, 5]);
}, 3000);
});
Ahora en cualquier otro lugar podemos llamar al
método then de nuestra promesa:
promise.then(function() {
// se activará al completarse la promesa
});
El resultado de la promesa llegará al primer parámetro de la función, si deseamos especificarlo:
promise.then(function(result) {
console.log(result); // mostrará el array con el resultado
});
Crea una promesa, dentro de la cual habrá un retraso
de 5 segundos, después del cual la promesa debe
completarse, devolviendo como resultado algún
texto. Muestra este texto en pantalla.