Bruno R

Como usar las promesas

x
portfolio-next-l5vb64p5k-bandikyu.vercel.app

Las promesas son la base de la programacion asincrona en JS moderno. Una promesa es un objeto devuelto por una funcion asincrona, que representa el estado actual de la operacion. En el momento que se devuelve la promesa al que llamo a la operacion, esta por lo general no a terminado, pero el objeto de la promesa proporciona metodos para manejar el eventual exito o fracaso de la operacion.

Usando la API fetch()

En este caso usando fetch aremos una peticion al servidor para recibir un archivo JSON (antiguamente se usaba XMLHttpRequestAPI pero ahora fetch seria su remplazo basado en promesas):

const fetchPromise = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');

console.log(fetchPromise);

fetchPromise.then( response => {
  console.log(`Received response: ${response.status}`);
});

console.log("Started request...");

Aca sucede lo siguiente:

Llamamos a una
El
Luego pasamos una funcion de controlador al metodo de promise
Y la ultima linea es basicamente para mostrar que iniciamos una solicitud, esta buena porque demuestra como el codigo se lee por completo y todavia no hay una respuesta por parte del servidor.

La salida completa debe ser algo como:

Promise { <state>: "pending" }
Started request...
Received response: 200

Esto probablemente se parece mucho al ejemplo del último artículo, donde agregamos controladores de eventos al XMLHttpRequestobjeto. En lugar de eso, estamos pasando un controlador al then()método de la promesa devuelta.?????

Encadenando promesas

Mediante la fetch API y obtener un objeto Response se utiliza otra funcion para obtener los datos de la respuesta, en este caso serian los datos en formato JSON, por lo que hariamos uso del metodo json() del objeto Response. Pero resulta que este metodo tambien es asincrono, por lo tanto tambien tendriamos que hacer uso de las promesas, porque si la promesa aun no tiene una respusta (positiva en el mejor de los casos), el metodo json se estaria ejecutando tambien sin esperar a que llegue, lo que desencadenaria un error, (claro esta que es porque se usaria el metodo de un objeto que no existe).

const fetchPromise = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');

fetchPromise.then( response => { //cuando llegue la respuesta, se va a ejecutar este codigo
  const jsonPromise = response.json(); //crea una constante donde se alamcena la respuesta en formato json()
  jsonPromise.then( json => { //esto se va a ejecutar cuando la constante tenga su respuesta gracias de nuvo al metodo then
    console.log(json[0].name); //devolvemos algo de contenido de la respusta .json
  });
});

Esto en parte se parece al infierno de callbacks, lo elegante de las promesas es que then devuelve un objeto promesa que se completara con el resultado de la funcion que se le paso.

Entonces podriamos cambiar la forma de escribirlo para que se vea mejor:

const fetchPromise = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');

fetchPromise
  
.then
( response => { //esto se va a ejecutar porque el response objeto llego
    return response.
json()
; //lo retornamos en formato json
  })//entonces esta parte es basicamente el response en formato json
  
.then
( json => { //then genera una promesa en base a la funcion asincrona planteada antes del punto
    console.log(json[0].name); //en el momento que tiene una respuesta, inicia su funcion
  });
/* esto es algo bastante mejor de entender y de gestionar que las funciones anidadas
vistas anteriormente en la gestion asincrona sin promesas

En lugar de llamar al segundo then() dentro del primer controlador then(), podemos devolver la promesa adquirida por json() y llamar al segundo then() para ese valor adquirido. Esto se denomina encadenamiento de promesas y significa que podemos evitar niveles cada vez mayores de sangria cuando cuando necesitamos realizar llamadas de funciones asincronas consecutivas.

verificando respuesta del servidor:

Podriamos agregar algo mas a nuestro codigo y esto seria verificar que el servidor acepto y pudo manejar la solicitud, antes de que intentemos leerla. Para esto verificaremos el estado de la respuesta y si no es “ok” enviamos un error.

const fetchPromise = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');

fetchPromise
  .then( response => {
    if (!response.ok) { //verificacion del estado de la respuesta "distinta de OK", esto es porque dentro del objeto hay una propiedad que puede tener valor "ok"
      throw new Error(`HTTP error: ${response.status}`);
    }
    return response.json();
  })
  .then( json => {
    console.log(json[0].name);
  });

Bibliografia

Glosario de palabras

Buscar conceptos