No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Callback hell

10/26
Recursos

Aportes 70

Preguntas 56

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Increible como mejoraron la calidad de este curso, cuando lo hice fue muy confuso pero nada que googleando no se solucione.

Y felicidades al profesor Oscar, la calidad de sus explicaciones ha mejorado demasiado; ojala hicieran otra vez el curso de webpack porque ha cambiado demasiado desde que lo hicieron.

🔥 𝗖𝗹𝗮𝘀𝗲 #𝟵: 𝗖𝗮𝗹𝗹𝗯𝗮𝗰𝗸 𝗵𝗲𝗹𝗹 𝟵/𝟮𝟭 🔥
.
CallBacks Hell: Consiste en múltiples Callbacks anidados que provocan que el código se vuelva difícil de leer y ‘debuggear’ y por eso se debe evitar.
.
✒️ Siguiendo con el proyecto:
.

  • Ir a la terminal, para compilar challenge.js se coloca: node src/callback/challenge.js
    Se obtiene las 3 salidas: el id, el título que corresponde al id y el nombre del tipo de categoría:
{ //console.log(data1[0]);
  id: 7,
  title: 'Probando TS ed',
  price: 666,
  description: 'Probando TS',
  category: {
    id: 5,
    name: 'Others',
    image: 'https://api.lorem.space/image?w=640&h=480&r=9607'
  },
  images: [
    'https://api.lorem.space/image?w=640&h=480&r=1583',
    'https://api.lorem.space/image?w=640&h=480&r=3215',
    'https://api.lorem.space/image?w=640&h=480&r=8220'
  ]
}
Probando TS ed //console.log(data2.title);
Others //console.log(data3.name);

  • Para ejecutar mediante un script, se edita el archivo package.json y en la parte de “scripts” se sustituye la línea: "test": "echo \"Error: no test specified\" && exit 1" por "callback": "node src/callback/challenge.js"
    Queda así:
"scripts": {
"callback": "node src/callback/challenge.js"
},

  • Se guarda con Ctrl + S y en la terminal, se ejecuta: npm run callback y debe aparecer la misma salida que node …

Este curso es un ejemplo de lo que es Platzi y de lo que debemos ser cada uno de nosotros. Esta versión mejoró mucho comparada a la anterior. Iterar y mejorar en cada iteración. De eso se trata. ¡Nunca pares de aprender!

Un breve resumen de callback código + comentario!! Espero que les sirve:

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // instanciamos xmlhttprequest.
const API = 'https://api.escuelajs.co/api/v1'; // API donde vamos a traer los datos.
// estados: 0 no iniciado - 1 cargando, aún no se llama a send - 2 cuando ya se ejecuto send
// 3 interactuando con la solicitud - 4 se ha completado la llamada.
// status: 200 solicitud correcta - 400 errores - 500 errores del servidor.
function fetchData(urlApi, callback) { // función donde generamos la conexión, recibe urlApi y un callback.
    let xhttp = new XMLHttpRequest(); // generamos una nueva instancia más corta en xhttp.
    xhttp.open('GET', urlApi, true); // abrimos una conexión con el método GET, urlApi y true para asincronismo.
    xhttp.onreadystatechange = function (event) { // cuando este cambio suceda, escuchamos el estado:
        if (xhttp.readyState === 4) { // comparamos el estado que sea igual a 4 (completado).
            if (xhttp.status === 200) { // comparamos el estatus sea igual a 200 (solicitud correcta).
                callback(null, JSON.parse(xhttp.responseText)); // retornamos callback null en error. Parse de datos.
            } else { // si lo anterior no ocurre:
                const error = new Error('Error' + urlApi); // generamos un nuevo error + urlApi.
                return callback(error, null); // retornamos callback con el error y null(para los datos).
            };
        };
    };
    xhttp.send(); // Enviamos el llamado o solitud.
};

llamados a la función fetchData:

// en el ejemplo se hacen varios llamados a modo de ejemplo, en el setTimeout del final se muestra la misma
// información de otra posición solo con el primer llamado, incluyendo el precio.
fetchData(`${API}/products`, function (error1, data1) { // llamamos la función con argumentos de url y func anónima.
    if (error1) return console.error(error1); // si se genera error retornamos error, info en data 1.
    fetchData(`${API}/products/${data1[0].id}`, function(error2, data2) { // volvemos a llamar a la función.
        if (error2) return console.error(error2); // retornamos error2 (si se produce) e info guardada en data2.
        fetchData(`${API}/categories/${data2?.category?.id}`, function(error3, data3) { // 3er llamado a la func.
            if (error3) return console.error(error3); // retorn. error3 (si se produce). Info guardada en data3.
            console.log(data1[0]); // mostramos los datos de la primer llamada (estudiar la api).
            console.log(data2.title); // mostramos los datos de la 2da llamada.
            console.log(data3.name); // 3er llamada.
        });
    });
    setTimeout( () => { // agregué este setTimeout para mostrar los mismos datos solo con el primer llamado a 5 seg.
        console.log(data1[1]); // se utilizó la posición 1 del array de la api para variar del ej. anterior.
        console.log(data1[1].title);
        console.log(data1[1].category.name);
        console.log(data1[1].price);
    }, 5000); // tiempo en milisegundos para ejecutar esos console.log.
});

las dos ultimas clases me rompieron la cabeza Dx

Para ejecutar en powershell es un poco distinto:

node .\src\callback\challenge.js

aviso por cualquier error
las diagonales son diagonales invertidas y antes de src se agrega: “ .\ ”

Otra opción a correr el código con node seria dirigirnos primero con cd al directorio que queremos y luego ejecutar node challenge

De verdad que es un dolor estudiar cualquier tema con este profesor.

Si no te corre el código después de actualizar Node.js y npm ni de reiniciar el pc. Copia y pega todos los archivos del professor y elimina los tuyos.
Funciona jajaja

Me encantó esa ultima parte en la que dice el profe que todo se pudo haber sacado de una sola petición 😃

Si les aparece el siguiente error. Deben actualizar NPM y nodeJS. ojalas les sirva.
[https://es.stackoverflow.com/questions/24268/cómo-actualizo-nodejs-en-windows]
SyntaxError: Unexpected token '.'
at wrapSafe (internal/modules/cjs/loader.js:1047:16)
at Module._compile (internal/modules/cjs/loader.js:1097:27)
at Object.Module._extensions…js (internal/modules/cjs/loader.js:1153:10)
at Module.load (internal/modules/cjs/loader.js:977:32)
at Function.Module._load (internal/modules/cjs/loader.js:877:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
at internal/main/run_main_module.js:18:47

En 3:40 alrededor se ve que al ejecutar el comando

node src/callback/challenge.js

Si se fijan hay un typo al poner ssrc en vez de src

Lo extraño es que el código en el ejemplo de la clase corrió y al principio lo puse así, por lo que salieron errores pero luego le quité una s al src y funcionó…

En gnu/linux:

node ./src/callback/file.js

Creo que modificaron el contenido de la API inicial
a mi me arroja otro objeto diferente:

{
  id: 1,
  title: 'Tasty Frozen Gloves',
  price: 134,
  description: 'The Football Is Good For Training And Recreational Purposes',
  category: {
    id: 5,
    name: 'Others',
    image: 'https://api.lorem.space/image?w=640&h=480&r=9727'
  },
  images: [
    'https://api.lorem.space/image?w=640&h=480&r=6198',
    'https://api.lorem.space/image?w=640&h=480&r=4521',
    'https://api.lorem.space/image?w=640&h=480&r=8417'
  ]
}
Tasty Frozen Gloves
Others

Callback Hell en JavaScript

El término “callback hell” (infierno de callbacks) se utiliza en el contexto de la programación en JavaScript para describir una situación en la que se anidan múltiples callbacks dentro de otros callbacks de una manera complicada y difícil de leer. Esto suele ocurrir cuando se trabaja con código asincrónico, como solicitudes HTTP, lectura/escritura de archivos o cualquier otra operación que no se resuelva de manera inmediata.

Aquí tienes un ejemplo de código que podría considerarse un “callback hell”:

function hacerAlgo(callback) {
  setTimeout(function() {
    console.log("Haciendo algo...");
    callback();
  }, 1000);
}

function hacerOtraCosa(callback) {
  setTimeout(function() {
    console.log("Haciendo otra cosa...");
    callback();
  }, 1000);
}

function hacerAlgoMas(callback) {
  setTimeout(function() {
    console.log("Haciendo algo más...");
    callback();
  }, 1000);
}

hacerAlgo(function() {
  hacerOtraCosa(function() {
    hacerAlgoMas(function() {
      console.log("Todas las tareas se han completado.");
    });
  });
});


En este ejemplo, las funciones hacerAlgo, hacerOtraCosa y hacerAlgoMas son funciones asincrónicas que toman callbacks como argumentos. Cuando quieres realizar estas acciones en secuencia, terminas anidando los callbacks uno dentro del otro, lo que hace que el código sea difícil de leer y mantener, especialmente cuando se tienen más funciones asincrónicas involucradas.

Para abordar el callback hell, puedes utilizar técnicas como Promesas (Promises) o async/await que hacen que el código asincrónico sea más legible y estructurado.

Aquí tienes el mismo ejemplo utilizando Promesas:

function hacerAlgo() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log("Haciendo algo...");
      resolve();
    }, 1000);
  });
}

function hacerOtraCosa() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log("Haciendo otra cosa...");
      resolve();
    }, 1000);
  });
}

function hacerAlgoMas() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log("Haciendo algo más...");
      resolve();
    }, 1000);
  });
}

hacerAlgo()
  .then(hacerOtraCosa)
  .then(hacerAlgoMas)
  .then(function() {
    console.log("Todas las tareas se han completado.");
  });


Este código utiliza Promesas para estructurar las tareas asincrónicas en una secuencia más clara y legible. Además, se evita la anidación excesiva de callbacks, lo que facilita el mantenimiento del código.

Espero sea de utilidad. 👨‍💻

El curso ya es algo viejo hoy en dia es mucho mas facil esto.
Yo lo hice usando axios:
En lugar de utilizar XMLHttpRequest, en Node.js puedes utilizar la biblioteca axios o node-fetch para realizar solicitudes HTTP. Estas bibliotecas proporcionan una interfaz más amigable y consistente para realizar solicitudes en Node.js.
Para instalarlo: npm install axios

Sin duda el profesor a diferente de los cursos anteriores ha mejorado bastante. Le entendi mucho más a diferencia antes.

Gracias, por la clase.

La calidad del curso mejoró demasiado

El término “Callback Hell” se refiere a una situación en la programación en JavaScript donde hay una anidación excesiva de funciones de devolución de llamada (callbacks), lo que resulta en un código difícil de leer, entender y mantener. Esto ocurre comúnmente cuando se utilizan múltiples operaciones asíncronas y cada una de ellas requiere una función de devolución de llamada para manejar los resultados.
.
Aquí tienes un ejemplo práctico de Callback Hell en JavaScript:

function hacerAlgo(parametro, callback) {
  // Simulando una operación asíncrona
  setTimeout(function() {
    console.log("Haciendo algo con " + parametro);
    callback();
  }, 1000);
}

function hacerOtraCosa(parametro, callback) {
  // Simulando otra operación asíncrona
  setTimeout(function() {
    console.log("Haciendo otra cosa con " + parametro);
    callback();
  }, 1000);
}

function hacerAlgoMas(parametro, callback) {
  // Simulando otra operación asíncrona
  setTimeout(function() {
    console.log("Haciendo algo más con " + parametro);
    callback();
  }, 1000);
}

// Uso de las funciones anidadas en un callback hell
hacerAlgo("A", function() {
  hacerOtraCosa("B", function() {
    hacerAlgoMas("C", function() {
      console.log("Todas las operaciones han terminado.");
      // Aquí podrías continuar con más código...
    });
  });
});

En este ejemplo, las funciones hacerAlgo(), hacerOtraCosa() y hacerAlgoMas() son operaciones asíncronas simuladas con setTimeout(). Cada una de estas funciones acepta un parámetro y una función de devolución de llamada que se ejecutará cuando se complete la operación.
.
El código se vuelve cada vez más anidado a medida que se agregan más operaciones asíncronas. Esto puede dificultar la lectura y el seguimiento del flujo del programa. Además, si se necesita realizar algún manejo de errores, la estructura del código se vuelve aún más compleja.
.
Para evitar el Callback Hell, se pueden utilizar técnicas como Promesas (Promises) o async/await, que proporcionan un enfoque más claro y estructurado para manejar operaciones asíncronas en JavaScript.

Muy buenas, yo me autopuse el reto de poder hacer lo mismo que hicimos en esta clase pero usando FETCH. Por lo que comparto mi codigo.

const API = 'https://api.escuelajs.co/api/v1';


async function hola (urlApi){
    const api = await fetch(urlApi);
    const data = await api.json();
    console.log(data[0]);
}

hola(`${API}/products/`);
bueno nose que sea esto pero , hice todo al pie de la letra corri y no daba busque no encontraba nada , por curiosidad copie el codigo del docente luego corri y si dio , volvi a poner mi codigo para ver que era lo que era distinto , y de la nada como por arte de magia ya daba mi codigo , no cambie absolutamente nada solo probe una ves con el del profe y luego con el mio corrio normal xD vaya cositas
que clase tan mala ....siempre es lo mismo Oscar cree que venimos sabiendo TODO, es obvio que venimos aprender y sus clases explica una parte y otras no y se pierde el ritmo de nosotros para seguirle....hay que investigar por nuestras propia cuenta paginas externas porque el no explica todo lo que hace y se vuelve tediosa la clase ...

me encanta la manera en que ha mejorado este curso, antes la verdad se me hacia mucho mas complicado y ahora se le ve una gran mejoria, desde contenido hasta la explicacion de Oscar, profe ha mejorado un monton muchas gracias

profe, creo que el modulo de la captura de errores no esta funcionanado bien. Quise cambiar el codido un poco para que me produjese un error, por ejemplo pidiendo que leyera una valor de data1\[100] y no captura el error debidamente.
ACTUALICEN LOS CURSOS...!!!

Esa api ya no sirve

Un buen video en español para complementar :
https://www.youtube.com/watch?v=iAq9SOEODvo

Para los que les da este error:

SyntaxError: Unexpected token .
at Module._compile

Usen estos comandos en este orden en la terminal para que su version de node.js se actualice y deje de dar ese error

  1. sudo npm cache clean --force
  2. sudo npm install -g n
  3. sudo n latest

A mi me funciono espero les sirva.

Como práctica, utilice al api de Rick & Morty, usando XMLHttpRequest.

API

https://rickandmortyapi.com/documentation/#rest

Código



const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;

const API= "https://rickandmortyapi.com/api";

function fetchData(apiUrl, funcioncita){
    let xhttp = new XMLHttpRequest();
    xhttp.open("GET", apiUrl, true);
    xhttp.onreadystatechange = function(event){
        if(xhttp.readyState === 4){
            if (xhttp.status === 200) {
                funcioncita(null, JSON.parse(xhttp.responseText));
            }else{
                const error = new Error('Esto es error '+apiUrl);
                return funcioncita(error, null);
            }
        }
    }
    xhttp.send();
}

fetchData(`${API}/character/3`, function(error1, data1){
    if(error1) return console.error(error1);
    // console.log(data1);
    console.log(data1.id);
    console.log(data1.name);
});

resultado

Comparto mi resumen en Notion de lo que va del curso…bueno supongo que cuando lo vean esté terminado.

https://deeply-warlock-d5d.notion.site/ASINCRONISMO-CON-JAVASCRIPT-67a33345a1984f6bb585d8d0c4d1375f

Tengo la siguiente consulto, el codigo lo verifique y esta bien mi version de node es la ultima v19.7.0 pero corro el codigo y nada pasa, alguno de ustedes saben que pasa, muestro imagen:

Fascinante…

Importante: Para que las peticiones HTTP funcionen tenemos que estar conectados a internet, o tener almacenado nuestro codigo en algun ambito de ejecucion.

de manera en la consola no funciona.

Mi aporte de CALLBACKS con peticiones a la API DE RICK AND MORTY:

            
let API = 'https://rickandmortyapi.com/api/'

function fetchData(apiURL,callback){
    let xhr = new XMLHttpRequest()
    xhr.open('GET',apiURL,true)
    xhr.onreadystatechange = function(e){
        if(xhr.readyState === 4){
            console.log(xhr.readyState)
            if(xhr.status === 200){
                console.log(xhr.status)
                callback(null, JSON.parse(xhr.responseText))
            }else{
                let error = new Error('HUBO UN ERROR')
                return callback(error)
            }
        }
    }
    xhr.send()
}



fetchData(`${API}/character`,function(error1,data1){
    if(error1) return console.error(error1)
    fetchData(`${API}/character/${data1.results[0].id}`,function(error2,data2){
        if(error2) return console.error(error2)
        fetchData(`${API}/location/${data2.id}`,function(err3,data3){
            if(err3) return console.error(err3)

            console.log(`Todos los personajes son: `)
            data1.results.forEach(e => console.log(e.name))
            console.log(`Pero elejiste el personaje: ${data2.name}`)
            console.log(`Y el personaje reside en: ${data3.name}`)
        })
    })
})

Comparto la API de pokemon que me sirvio para hacer pruebas, ya que la fakeApi de Platzi esta caida por ahora, https://pokeapi.co/api/v2, exito!

Obtener todos los productos:

const xmlhttp = require('xmlhttprequest').XMLHttpRequest;
const open = require('open')

const API = 'https://api.escuelajs.co/api/v1';

function obtenerDatos(urlAPI, callback) {
    let xhttp = new xmlhttp();

    xhttp.open('GET', urlAPI, true);
    xhttp.onreadystatechange = function(event) {
        if(xhttp.readyState === 4) {
            if(xhttp.status === 200) {
                callback(null, JSON.parse(xhttp.responseText));
            }
        } else {
            let error = new Error('error ' + urlAPI);
            return callback(error, null);
        }
    }
    xhttp.send();
}

obtenerDatos(`${API}/products`, function(error1, data1) {
    if(error1) return console.log(error1);
    console.log(data1);
});
por qué es tan difícil pronunciar S R C en vez de C R C? Es español, no debería ser tan complicado.

sii miramos con fetch porfa, y si es posible con axios asi sea una libreria externa

ctrl + a selecciona todo el codigo 🙆
Les recomiendo que comparen el código escrito por el profesor en el área de recursos y el desarrollado por ustedes mismos para que se hagan idea de las diferencias que puedan tener, por ejemplo en los casos en que al darle 'Run Code' en la terminal se indica que funciono sin errores, pero no muestra ni despliega contenido. Código de la clase: ```js const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; const API = 'https://api.escuelajs.co/api/v1'; function fetchData(urlApi, callback) { let xhttp = new XMLHttpRequest(); xhttp.open('GET', urlApi, true); xhttp.onreadystatechange = function (event) { if (xhttp.readyState === 4) { if (xhttp.status === 200) { callback(null, JSON.parse(xhttp.responseText)); } else { const error = new Error('Error' + urlApi); return callback(error, null); } } } xhttp.send(); } fetchData(`${API}/products`, function (error1, data1) { if (error1) return console.error(error1); fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) { if (error2) return console.error(error2); fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) { if (error3) return console.error(error3); console.log(data1[0]); console.log(data2.title); console.log(data3.name); }); }); }); ```const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; const API = 'https://api.escuelajs.co/api/v1'; function fetchData(urlApi, callback) { let xhttp = new <u>XMLHttpRequest</u>(); xhttp.open('GET', urlApi, true); xhttp.onreadystatechange = function (event) { if (xhttp.readyState === 4) { if (xhttp.status === 200) { callback(null, <u>JSON</u>.parse(xhttp.responseText)); } else { const error = new <u>Error</u>('Error' + urlApi); return callback(error, null); } } } xhttp.send(); } fetchData(`${API}/products`, function (error1, data1) { if (error1) return <u>console</u>.error(error1); fetchData(`${API}/products/${data1\[0].id}`, function (error2, data2) { if (error2) return <u>console</u>.error(error2); fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) { if (error3) return <u>console</u>.error(error3); <u>console</u>.log(data1\[0]); <u>console</u>.log(data2.title); <u>console</u>.log(data3.name); }); }); });
no carga fake api? ![](https://static.platzi.com/media/user_upload/fakeapi.platzi.com%20-%20Google%20Chrome%2027_01_2024%2018_07_28-96e91e7e-6a58-4464-827e-8e3173fcf88a.jpg)
no me sale T.T

Que onda platzinautas 💚, comparto mis notas del ejercicio por si se les facilita el entendimiento del calback hell:

//! Creacion del XMLHttpRequest

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest
const API = 'https://api.escuelajs.co/api/v1'

function fetchData(urlApi, callball) {
    
    // Se crea un objeto XMLHttpRequest
    let xhttp = new XMLHttpRequest()

    // Abrimos una conexion indicando (tipo de solicitud, url, si la solicitud es asincronica [true])
    xhttp.open('GET', urlApi, true)

    // Se configura un evento onreadystatechange que se ejecutará cada vez que cambie el estado de la solicitud. 
    xhttp.onreadystatechange = function (event) {
        
        // Cuando la solicitud se completa con éxito (estado 4 y estado HTTP 200), se procesa la respuesta
        // En este caso transformamos el texto que retorna a un formato JSON
        // En caso fallido mandamos un error
        if(xhttp.readyState === 4){
            if(xhttp.status === 200){
                callball(null, JSON.parse(xhttp.responseText))
            } else {
                const error = new Error('Error' + urlApi)
                return callball(error, null)
            }
        }
    }

    // Se envía la solicitud con el método send()
    xhttp.send()
}

//! Callback hell: cuando se realizan varias peticiones en un solo espacio
//* Realizamos varias peticiones para obtener los datos necesarios, casi como un for con concatenacion
/*
    * data1: Todos los productos
    * data2: El primer producto del objeto productos -> Recycled Frozen Salad con id 4
    * data3: La categoria correspondiente al primer producto -> Clothes con id 1
*/
// 1. Peticion a productos
// UrlEjemplo: https://api.escuelajs.co/api/v1/products
fetchData(`${API}/products`, function (error1, data1){

    //Si ocurre un error imprime ese error
    if(error1) return console.error(error1);

    // 2. Peticion a el primer producto individual  
    // UrlEjemplo: https://api.escuelajs.co/api/v1/products/4
    fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {

        if(error2) return console.error(error2);

        // 2. Peticion a la categoria correspondiente al primer producto individual
        // UrlEjemplo: https://api.escuelajs.co/api/v1/categories/1
        fetchData(`${API}/categories/${data2?.category?.id}`, function (error3, data3) {
            
            if(error3) return console.error(error3);

            console.log(data1[0]);
            console.log(data2.title);
            console.log(data3.name);

        })
    })
})

Ejemplo simple para entender el callback hell

Supongamos que queremos hacer una llamada al servidor API en callback hell in JavaScript. Para ello, se crea una promesa (promise 1) con una gestión de respuesta (response). Ahora, pensemos que queremos ejecutar una acción asincrónica distinta que depende de esta respuesta. Entonces, crearemos otra promesa (promise 2) anidada a la primera. Esta promesa, a su vez, debe gestionarse con un método then. Aquí hemos empezado un árbol de promesas que puede detenerse o continuar del callback hell in JavaScript.

Este ciclo de promesas puede continuar cada vez que queramos ejecutar una acción dependiente del resultado anterior y gestionarla. Este árbol de promesas se vería similar a las líneas de código que te mostramos a continuación, cada una ejecutando una acción individual, pero que impacta en las demás:

// llamar al servidor
p1.then (response => {
// enviar los datos a la db
p2.then (response2 {
// recoger el resultado de la db y escribirlo en un log
p3.then (response3 => {
// cuando el log pasa de 3MB, subirlo a un s3
p4.then (response4 => {
p5.then (response5 => {
}

En las líneas de código anteriores, hemos hecho que los comportamientos que queremos ir gestionando se aniden, creando una dependencia de referencias eterna. A esta anidación de acciones la llamamos callback hell en JavaScript. **Esta situación es tan conocida en el mundo de la programación que tiene su propia página web. Además, el proceso que nos lleva a ella se conoce como highway to callback hell. Por ello, te invito a leer la página **callbackhell.com** para conocer más sobre este fenómeno de callback hell.

La anidación de acciones a ejecutar o callback hell también puede suceder cuando usamos los condicionales if …else, que nos ayudan a plantear situaciones en las que una acción sucede si algo pasa y otra si esto no pasa. Para conocer más sobre este condicional, te invito a leer este post sobre cómo usar if else else en JavaScript, relacionado al callback hell in JavaScript. Esta situación es relativamente fácil de romper cuando utilizamos if, pero no es el caso de las promesas.

hagan debug de las peticiones, entenderán mejor como funciona el código.

En la terminal no me corría el comando, me salía error pero me percate que no lo había guardado en vsc y le di Control + s y listo, me corrió en la terminal ;D

‼️⚠️ Al momento de crear este comentario (22/03/2023) hay un error en la API. Parece que varios productos no existen y regresan un error. Al usar concurrencia en el ejercicio casi creamos un loop infinito sin querer. Por suerte los productos existen a partir de un numero determinado, en mi caso el producto 16.
Ya reporté este error al equipo, no es error de su código. El error es:

Error: Error https://api.escuelajs.co/api/v1/products at xhttp.onreadystatechange (D:\Desarrollo\JavaScript\curso-asincronismo\src\callback\challenge.js:26:18) at exports.XMLHttpRequest.dispatchEvent (D:\Desarrollo\JavaScript\curso-asincronismo\node_modules\xmlhttprequest\lib\XMLHttpRequest.js:591:25) at exports.XMLHttpRequest.send (D:\Desarrollo\JavaScript\curso-asincronismo\node_modules\xmlhttprequest\lib\XMLHttpRequest.js:396:12) at fectchData (D:\Desarrollo\JavaScript\curso-asincronismo\src\callback\challenge.js:32:8) at Object.<anonymous> (D:\Desarrollo\JavaScript\curso-asincronismo\src\callback\challenge.js:36:1) at Module._compile (node:internal/modules/cjs/loader:1275:14) at Module._extensions..js (node:internal/modules/cjs/loader:1329:10) at Module.load (node:internal/modules/cjs/loader:1133:32) at Module._load (node:internal/modules/cjs/loader:972:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
Hay muchas preguntas al respecto. Y es debido a este error.

AAAAAA SI ME SALIO, EMOCIONAO

10/26 Callback hell
Imagina que tienes una serie de tareas que necesitas hacer, pero algunas de ellas son asíncronas, lo que significa que toman tiempo en completarse. Para manejar estas tareas, utilizas callbacks, que son funciones que se ejecutan cuando una tarea asíncrona ha terminado

El CallBackHell ocurre cuando tienes muchas tareas asíncronas que se anidan unas dentro de otras, lo que hace que el código se vuelva difícil de leer y entender. Esto sucede cuando un callback se coniverte en un argumento de otro callback, y esto se repite varias veces.

hacerAlgo(function(resultado1) {
  hacerOtraCosa(resultado1, function(resultado2) {
    hacerAlgoMas(resultado2, function(resultado3) {
      // y así sucesivamente...
    });
  });
});

En este ejemplo tienes tres tareas diferentes (hacer algo hacerotracosa y haceralgomas) que se ejecutan de manera asíncrona. Cada una de ellas toma como argumento un callback, y dentro de ese callback se llama a la siguiente tarea.

A medida que anidas más y más callbacks, el código se vuelve más difícil de leer y mantener. Esto se debe a que tienes muchas llaves y paréntesis y puede ser confuso seguir el flujo del programa.

El CallBackHell puede ser problematico porque dificulta la comprensión del código, aumenta la posibilidad de cometer errores y hace que el mantenimiento sea complicado. Afortunadamente existen soluciones como las promesas o el uso de async/await, que ofrece una sintaxis más clara y estructurada para manejar tareas asíncronas y evitar caer en un CallBackHell

challenge.js

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const API = "https://api.escuelajs.co/api/v1";

function fetchData(url) {
  return new Promise((resolve, reject) => {
    const xhttp = new XMLHttpRequest();

    xhttp.open("GET", url, true);
    xhttp.onreadystatechange = function () {
      if (xhttp.readyState === 4) {
        if (xhttp.status === 200) {
          const response = JSON.parse(xhttp.responseText);
          resolve(response);
        } else {
          reject(new Error("Error: " + url));
        }
      }
    };
    xhttp.send();
  });
}

async function obtenerDatos() {
  try {
    const data = await fetchData(`${API}/products`);
    const product = await fetchData(`${API}/products/${data[2].id}`);
    const category = await fetchData(
      `${API}/categories/${product?.category?.id}`
    );

    console.log(data[0]);
    console.log(product.title);
    console.log(category.name);
  } catch (error) {
    console.error("¡Hubo un error!", error);
  }
}

obtenerDatos();

Hola, tuve problemas para que se ejecuta el api, para resolverlo agregue

,
“type”: “module”

en el archivo package.json. Luego cambie el const XMLHttpRequest por:

import { XMLHttpRequest } from "xmlhttprequest"

y por ultimo verifique que las rutas en las llamadas de fetch data tengan sus “/” necesarios, que es justo como lo tiene el profesor.
Haciendo eso, el api me funciono de maravilla, espero que esto le sirve a alguien. 😁

Les comparto mi código comentado por chatgpt espero q les sea de ayuda

// Import the XMLHttpRequest class from the xmlhttprequest module and define the API URL and some constants
const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const API = "https://api.escuelajs.co/api/v1";

// Define a function taking an URL and a callback function as parameters
function fetchData(urlApi, callback) {
  const xhttp = new XMLHttpRequest(); // Initialize a new XML HTTP Request
  xhttp.open("GET", urlApi, true); // Set the request method to GET and the URL
  xhttp.onreadystatechange = () => {
    // Define the onreadystatechange event listener to handle the response
    if (xhttp.readyState === 4) {
      // Only execute this code once the request is completed successfully
      if (xhttp.status === 200) {
        // Check if the status code is 200 OK
        callback(null, JSON.parse(xhttp.responseText)); // Execute the callback function with null error and parsed JSON response data
      } else {
        const error = new Error("Error" + urlApi); // Create a new error object with the current URL
        return callback(error, null); // Return the error object to the callback function
      }
    }
  };
  xhttp.send(); // Send the request
}

// Call the fetchData function with the products endpoint URL and a nested callback chain to get related product category and name information
fetchData(`${API}/products`, function (error1, data1) {
  if (error1) return console.log(error1); // Handle errors in case they occur during the first request
  fetchData(`${API}/products/${data1[0].id}`, function (error2, data2) {
    if (error2) return console.log(error2); // Handle errors in case they occur during the second request
    fetchData(
      `${API}/categories/${data2?.category?.id}`,
      function (error3, data3) {
        // Final nested callback handles potential error and logs all three data properties
        if (error3) return console.log(error3);
        console.log(data1[0]);
        console.log(data2.title);
        console.log(data3.name);
      }
    );
  });
});

Verifiquen bien sus codigos compañeros, yo puse reatyState y estuve como 1 hora buscando que salio mal.

No entendí, al menos se como funciona el código pero a la hora de aplicarlo ni idea de como hacerlo solo, en conclusión no entendixd

Oscar la gesticulacion (Movimiento de tus manos) debe ser mas natural o controlada, ya que distrae mucho !!

Descripcion grafica Callback Hell

Ok tendre que hacer uso de otra API, para poder seguir con los ejemplos y entender mejor.

a mi me muestra el id 4:
id: 4,
title: ‘Bespoke Steel Computer’,
price: 60,
description: ‘Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support’,
images: [
https://api.lorem.space/image/fashion?w=640&h=480&r=3981’,
https://api.lorem.space/image/fashion?w=640&h=480&r=6655’,
https://api.lorem.space/image/fashion?w=640&h=480&r=7982
],
creationAt: ‘2023-01-04T21:52:29.000Z’,
updatedAt: ‘2023-01-04T21:52:29.000Z’,
category: {
id: 1,
name: ‘Clothes’,
image: ‘https://api.lorem.space/image/fashion?w=640&h=480&r=9685’,
creationAt: ‘2023-01-04T21:52:29.000Z’,
updatedAt: ‘2023-01-04T21:52:29.000Z’
}
}
Bespoke Steel Computer
Clothes

casi medio pelo!

hola si les sale este error
throw err;

lo que hice y me funciono :
-Es probable que el módulo también deba instalarse localmente para el proyecto.

¿Tiene un archivo package.json? Si es así, ejecuta:
npm install --save xmlhttprequest

https://stackoverflow.com/questions/31776636/node-js-cannot-find-an-installed-module

Callback Hell
Es un conjunto de múltiples Callbacks anidados, esto puede provocar errores en la lectura e interpretación del código.
Esto se suele dar dado que no se planifica bien el código que se va a escribir y se piensa que el código será secuencial.
Cómo evitar el Callback Hell

  • Código modular

  • Nombrar las funciones mnemotécnicamente

  • Declarar las funciones al principio del código

hasta tiene su propia pagina esta clase 😂

CALLBACK HELL .com

Actualización de xmlHttpRequest 2022

https://stackoverflow.com/questions/32604460/xmlhttprequest-module-not-defined-found

2022 update: Node 18 has a native implementation of fetch enabled by default.

If you really want to use XHR in Node.js then there are a couple of third party implementations. xmlhttprequest (which seems to be unmaintained) and xhr2 (which has had an update this year).

Install it with npm,

npm install xhr2
Now you can require it in your code.

var XMLHttpRequest = require(‘xhr2’);
var xhr = new XMLHttpRequest();

//instalacion gestor de paquetes nvm y node js
sudo apt-get update
sudo apt-get install nodejs

sudo apt-get update
sudo apt-get install build-essential libssl-dev
curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh -o install_nvm.sh
nvm ls-remote (para saber la ultima version)
nvm install 16.17.0

Fuente:https://www.digitalocean.com/community/tutorials/como-instalar-node-js-en-ubuntu-16-04-es

const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
const API = 'https://api.escuelajs.co/api/v1';

function fetchData(urlApi, callback){
  let xhttp = new XMLHttpRequest();

  xhttp.open('GET', urlApi, true);
  xhttp.onreadystatechange = function(event){
    if(xhttp.readyState === 4){
      if(xhttp.status === 200){
        callback(null, JSON.parse(xhttp.responseText));
      }else{
      const error = new Error('Error' + urlApi);
      return callback(error, null);
      }
    }
  }  
  xhttp.send();
}


fetchData(`${API}/products`, function(error1, data1){
  if (error1) return console.error(error1);
  fetchData(`${API}/products/${data1[0].id}`, function(error2, data2){
    if (error2) return console.error(error2);
    fetchData(`${API}/categories/${data2?.category?.id}`, function(error3, data3){
      if (error3) return console.error(error3);
      console.log(data1[0]);
      console.log(data2.title);
      console.log(data3.name);
    });
  });
});

Como venía del curso de ECMAScript quise ir construyendo mi versión con arrow functions, además del salto de linea con las comillas ``, aquí mí versión:

/*Practice using the API from Platzi https://fakeapi.platzi.com/ in order to work asynchronism taking advantage of the modula XMLHTTPRequest*/
 const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
 const API = 'https://api.escuelajs.co/api/v1';

 function fetchData(urlApi, callback){
    let xhttp = new XMLHttpRequest();

    xhttp.open('GET', urlApi,true);
    xhttp.onreadystatechange = (event) => {
        if(xhttp.readyState === 4){ //4 means the call has been completed
            if(xhttp.status ===200){ //session is correct
                callback(null,JSON.parse(xhttp.responseText));
            }else {
                const error = new Error('Error' + urlApi);
                return callback(error,null);
            }
        } 
    }
    xhttp.send();
 }

 fetchData(`${API}/products`, (error1,data1)=>{ //callback hell format just for study purposes
    if(error1) return console.error(error1);
    fetchData(`${API}/products/${data1[0].id}`, (error2,data2) =>{
        if(error2) console.error(error2);
        fetchData(`${API}/categories/${data2?.category?.id}`, (error3,data3)=>{
            if(error3) return console.error(error3);
            console.log(`${JSON.stringify(data1[0])}
            ________________________
                        ${data2.title}
            --------------------------
                        ${data3.name}`);
        });
    });
 });

me sumo a la petición de webpack actualizado
es buena práctica los callback hell?