Bruno R
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.
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:
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.?????
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.
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); });
Glosario de palabras
Buscar conceptos