Clase de Promise en JavaScript

Clase de Promise en JavaScript

En este artículo, explicamos la clase Promise en JavaScript.

YouTube Video

Promise

La clase Promise es una clase para manejar operaciones asíncronas. Gestiona los resultados si la operación tiene éxito o maneja errores si falla. Tradicionalmente, se usaban funciones de callback cuando necesitabas esperar a que una operación asíncrona terminara, pero Promise hace esto más claro y poderoso.

1const promise = new Promise((resolve, reject) => {
2    setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
  • Este código es un ejemplo de un proceso asíncrono que muestra "¡Hecho!" después de un segundo.
    • Primero, se crea un nuevo objeto Promise utilizando new Promise. El argumento es una función que recibe dos callbacks: resolve para el éxito y reject para el fallo.
    • Se utiliza setTimeout para llamar a resolve() después de un segundo.
    • El método then() del objeto promise espera a que se complete y muestra el resultado.

Estructura Básica

Una Promise es un objeto que finalmente resulta en éxito o fracaso.

 1const promise = new Promise((resolve, reject) => {
 2    // Asynchronous operation
 3    // Flag indicating whether the operation was successful
 4    const success = true;
 5
 6    if (success) {
 7        resolve('Operation successful!');
 8    } else {
 9        reject('An error occurred');
10    }
11});
  • En el caso de éxito, se llama a resolve().
  • En el caso de fracaso, se llama a reject().

El objeto Promise tiene tres estados.

1promise
2    .then((result) => {
3        console.log(result);
4    })
5    .catch((error) => {
6        console.error(error);
7    })
  • Pendiente
    • El proceso asíncrono aún no se ha completado.
  • Cumplido
    • El proceso asíncrono tuvo éxito y el resultado fue devuelto por resolve(). El resultado se recibe utilizando el método then().
  • Rechazado
    • El proceso asíncrono falló y ocurrió un error a través de reject(). El error se recibe utilizando el método catch().

Métodos then() y catch()

Usando un Promise, puedes definir qué hacer cuando se complete una operación asíncrona. Para esto, usas los métodos then() y catch().

then()

1const promise = new Promise((resolve, reject) => {
2    resolve('Operation successful!');
3});
4
5promise.then((result) => {
6    console.log(result);  // "Operation successful!"
7});
  • El método then() especifica una función que se llamará cuando el Promise tenga éxito.

catch()

1const promise = new Promise((resolve, reject) => {
2    reject('An error occurred');
3});
4
5promise.catch((error) => {
6    console.error(error);  // "An error occurred"
7});
  • El método catch() especifica una función que se llamará cuando el Promise falle.

Método finally()

 1const promise = new Promise((resolve, reject) => {
 2    resolve('Operation successful!');
 3});
 4
 5promise
 6    .then((result) => {
 7        console.log(result);
 8    })
 9    .catch((error) => {
10        console.error(error);
11    })
12    .finally(() => {
13        console.log('The operation has completed');
14    });
  • El método finally() define un código que se ejecutará al final independientemente de si el Promise tuvo éxito o falló.

Cadena de then()

then() devuelve una nueva Promise, así que puedes encadenar el siguiente then().

 1const promise = new Promise((resolve, reject) => {
 2    setTimeout(() => {
 3        resolve(1);
 4    }, 1000);
 5});
 6
 7promise
 8    .then(result => {
 9        console.log(result); // 1
10        return result + 1;
11    })
12    .then(result => {
13        console.log(result); // 2
14        return result + 1;
15    })
16    .then(result => {
17        console.log(result); // 3
18    })
19    .catch(error => {
20        console.error(error.message); // Something went wrong
21    });
  • En este código, el resolve() inicial pasa el valor 1, y cada valor devuelto por un then se pasa al siguiente then.
  • Usando catch(), puedes manejar cualquier error que ocurra en la cadena en un solo lugar.

Ejemplo Práctico

Por ejemplo, los Promises suelen utilizarse para obtener datos de un servidor. Veamos un ejemplo usando la API fetch().

 1fetch('https://codesparklab.com/json/example.json')
 2    .then(response => {
 3        if (!response.ok) {
 4            throw new Error('Network error');
 5        }
 6        return response.json();
 7    })
 8    .then(data => {
 9        console.log(data);
10    })
11    .catch(error => {
12        console.error('Error:', error);
13    });
  • En este código, dado que fetch() devuelve un Promise, se utiliza then() para procesar los datos después de recibir una respuesta del servidor. Los errores se manejan usando catch().

Manejando Múltiples Promesas

Promise.all()

Para ejecutar múltiples Promises simultáneamente y continuar solo si todos tienen éxito, utiliza Promise.all().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • then() se llama solo si todos los Promises tienen éxito. catch() se llama si falla incluso uno.

Promise.allSettled()

Si quieres ejecutar múltiples Promises simultáneamente y obtener todos los resultados sin importar si tuvieron éxito o fallaron, utiliza Promise.allSettled().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • then() se llama una vez que todas las Promise se han asentado (ya sea cumplidas o rechazadas). Cada resultado incluye una propiedad status ('fulfilled' o 'rejected'). Incluso si algunas fallan, no afecta a las demás operaciones.

Promise.race()

Promise.race() devuelve el resultado de la Promise que se resuelva primero, ya sea cumplida o rechazada.

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • Como en este ejemplo, se devuelve el resultado del primer Promise completado.

Relación con async/await

Usar la sintaxis async/await te permite escribir Promises de manera más intuitiva. Una función async siempre devuelve una Promise, y await espera a que la Promise se resuelva.

 1async function fetchData() {
 2    try {
 3        const response = await fetch('https://codesparklab.com/json/example.json');
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error('Error :', error);
 8    }
 9}
10
11fetchData();

Al usar async/await de esta manera, las operaciones asíncronas pueden escribirse como código sincrónico, lo que las hace más fáciles de leer.

Resumen

  • Promise es un objeto para gestionar el éxito o el fallo de operaciones asíncronas.
  • Gestiona las operaciones exitosas con then() y los errores con catch().
  • finally() define el código que se ejecuta al final, independientemente de si tiene éxito o falla.
  • Puedes gestionar varias Promises a la vez usando Promise.all() o Promise.race().
  • async/await es una sintaxis para escribir Promises de manera más sencilla.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video