Introducción al curso

1

¡Alto! Tenemos una nueva versión de este curso para ti

2

Bienvenidos al Curso de Fundamentos de JavaScript

3

Repositorio de este curso de fundamentos de JS

Primeros pasos en JavaScript

4

Variables

5

Variables: Strings

6

Variables: Números

7

Funciones

8

El alcance de las funciones

9

Objetos

10

Desestructurar objetos

11

Parámetros como referencia o como valor

12

Comparaciones en JavaScript

Estructuras de Control y Funciones

13

Condicionales

14

Funciones que retornan valores

15

Arrow functions

16

Estructuras repetitivas: for

17

Estructuras repetitivas: while

18

Estructuras repetitivas: do-while

19

Condicional múltiple: switch

Arrays

20

Introducción a arrays

21

Filtrar un array

22

Transformar un array

23

Reducir un array a un valor

Programación Orientada a Objetos en JavaScript

24

Cómo funcionan las clases en JavaScript

25

Modificando un prototipo

26

El contexto de las funciones: quién es this

27

La verdad oculta sobre las clases en JavaScript

28

Clases en JavaScript

Asincronismo

29

Funciones como parámetros

30

Cómo funciona el asincronismo en JavaScript

31

Cómo funciona el tiempo en JavaScript

32

¿Qué pasó con swapi.co?

33

Callbacks

34

Haciendo múltiples requests

35

Manejando el Orden y el Asincronismo en JavaScript

36

Manejo de errores con callbacks

37

Promesas

38

Promesas Encadenadas

39

Múltiples promesas en paralelo

40

Async-await: lo último en asincronismo

Juego de HTML

41

Comenzando el juego

42

Generando una secuencia de números

43

Iluminando la secuencia de colores

44

Obteniendo el input del usuario

45

Agregando la verificación del color elegido

46

Agregando los estados finales del juego

47

Conclusiones del curso

Complementos

48

Diferencias entre var, let y const

49

Memoización: ahorrando cómputo

50

¿Hace cuántos días naciste?

51

Funciones recursivas

52

Entiende los closures de JavaScript

53

Estructuras de datos inmutables

54

Cambiando de contexto al llamar a una función

55

¿Cuándo hace falta poner el punto y coma al final de la línea?

No tienes acceso a esta clase

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

Manejando el Orden y el Asincronismo en JavaScript

35/55
Recursos

Una manera de asegurar que se respete la secuencia en que hemos realizado múltiples tareas es utilizando callbacks, con lo que se ejecutará luego, en cada llamada. Lo importante es que el llamado al callback se haga a través de una función anónima. Sin embargo, al hacerlo de esta manera generamos una situación poco deseada llamada CallbackHell.

Aportes 230

Preguntas 49

Ordenar por:

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

Resumen de la clase
Manejo del Orden y el Asincronismo de JavaScript

Agregamos primero otro parámetro a la función obtenerPersonaje().

obtenerPersonaje(id, callback)

Movemos la variable de la función al $.get.

$.get(url, opts, function(people){
    console.log(people.name)
})

Si queremos que lleguen en orden tenemos que hacer los requests uno después del otro y no en paralelo como los veníamos haciendo.
Para eso usamos el segundo parámetro en la función.

function obtenerPersonaje(id, callback) {
    const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`
    $.get(url, opts, function(people){
        console.log(people.name)
    })
    if(callback) {
        callback()
    }
}

Así podemos invocar la función del callback de la siguiente manera:

obtenerPersonaje(1, function() {
    obtenerPersonaje(2, function() {
        obtenerPersonaje(3, function() {
            obtenerPersonaje(4)
        })
    })
})

Pero esto trae la problemática del anidamiento infinito llamado CallbackHell.

Eso de encadenar callbacks es una pesima practica, se le denomima ‘callbacks hell’ y produce la espaguetización del código. Era algo muy comun en la epoca de jQuery ahce algunos años. Por suerte ahora tenemos las Promesas y async/await para solucionar eso.

Les comparto mi callbackhell multicolor

porqué el servidor entrega las consultas en desorden ?
Gracias 😄 !!

Chicos,
Pregunta para sacarme a duda, cuando preguntamos if(callback) esta pregutando si esta definido ese parametro no? en caso de que no quiere decir que no hay invocacion anidada no?
Te marea este concepto jajaj, mil gracias!
Slds.

Interesante…mi primer Infierno de Callbacks 😃 😃!!!

viendo los comentarios me da miedo ponerle play jajajaj

Callback hell!!!

Tiene su chiste el asincronismo! No creí que fuera tan complejo

Si queremos traer n personajes en orden, podemos usar un for donde en la primera iteracion llamamos a la funcion ObtenerNombre con el indice i y en el callback la misma funcion pero con el indice i+1

const API_URL = 'https://swapi.co/api/'
        const PEOPLE_URL = 'people/:id'


        const options = { cossDomain: true }


        function obtenerPersonaje(id, callBack) {
            const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`
            $.get(url, options, onResponse = (persona) => console.log(`Hola yo soy ${persona.name} y mido ${persona.height}`))
        }
        // Obetener 15 personajes
        for (let i = 1; i <= 15; i++) {
            obtenerPersonaje(i, function () {
                obtenerPersonaje(i + 1)
            });
        }```

Callbacks Heeell!!
Es un buen titulo para una película 😄

Si recargo varias veces el orden sigue siendo aleatorio, a alguien tambien le pasa?

este es mi código

const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'
const opts = { crossDomain: true }
const onPeopleResponse = ({ name }) => console.log(`Hola, yo soy ${name}`)

function obtenerPersonaje(id, callback) {
	const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`
	$.get(url, opts, onPeopleResponse)

	if (callback) {
		callback()
	}
}


/* Para garantizar el orden en el que se reciben los datos usamos callback
LOS REQUESTS SE HACEN EN SERIE
*/
obtenerPersonaje(1, function() {
	obtenerPersonaje(2, function() {
		obtenerPersonaje(3, function() {
			obtenerPersonaje(4, function() {
				obtenerPersonaje(5, function() {
					obtenerPersonaje(6, function() {
						obtenerPersonaje(7)
					}) // 6
				}) // 5
			}) // 4
		}) // 3
	}) // 2
}) // 1

Espero volver del futuro pronto, y ofrecer una solución elegante mediante una función recursiva.

No sé si sea la mejor manera pero encontre que con arrow function es más sencillo usar los callback

const API_URL = 'https://swapi.dev/api/'
const PEOPLE_URL = 'people/:id'

const opts = {crossDomain: true}



function getCharacter(id, callback ){ //Callback puede ser nombrado como fn (de function) o cb (de callback)
    const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`

    $.get(url, opts, person => {
        console.log(`Hi, I'm ${person.name}`)
        if(callback){
            callback()
        }
    })
}

getCharacter(1, 
        () => getCharacter(2,
        () => getCharacter(3,
        () => getCharacter(4)
)))

Usando recursividad queda bien:

const API_URL = "https://swapi.co/api/";
const PEOPLE_URL = "people/:id";
const opts = { crossDamain: true };

function obtenerPersonaje(id, callback) {
	const url = `${API_URL}${PEOPLE_URL.replace(":id", id)}`;
	$.get(url, opts, function(persona) {
		console.log(`Hola, yo soy ${persona.name}`);
		if (callback) {
			callback();
		}
	});
}

var i = 0;
repetir();
function repetir() {
	if (i == 10) {
		return;
	}
	obtenerPersonaje(++i, function() {
		repetir();
	});
}

Evitar HellCallbacks

**Callback hell! **

Buenas, aquí les dejo mi versión de callbacks usando recursividad (funciones que se llaman a si mismas)

const API_URL='https://swapi.co/api/'
const PEOPLE_URL='people/:id'
const OPT= { crossDomain: true}

function buscar_2(id, fn){
  let url=`${API_URL}${PEOPLE_URL.replace(':id',id)}`
  $.get(url,OPT, function(obj){
    console.log(obj.name)
    if (fn){
      fn()
    }
  })
}

//la recursividad se define como una funcion que se llama a si misma
//Las llamadas se apilan (LIFO)
//Se puede trabajar de subida (codigo que se ejecuta antes de realizar a la llamada)
//O de bajada (codigo que se ejecuta despues de la llamada)

function recursiva_2(num){
  num=num+1
  buscar_2(num, function(){
    if (num<5){
      recursiva_2(num)
    }
  })

}

recursiva_2(0)

//Se uso Jquery para hacer los request a una API de star wars
//Los callbacks son funciones que se pasan como parametros que se ejecutan luego de la function que los paso

Un aporte usando vanilla JS. Al final un pequeño reto-- 😃

//Url de mi server osea la api de star wars
const urlApi = 'https://swapi.dev/api/';
//Podemos elegir entre personajes, planetas y naves
const character = 'people/:id';

//El id selecciona el personaje y callback sera una funcion anidada
//Para que se apilen en el callstack, asi no se ejecutaran de manera líneal
//Esto con la finalidad de hacer el llamado de manera ordenada
function getInformation(id,callback){
    //Cambio el id para elegir un personaje especifico
    var url = `${urlApi}${character.replace(':id',id)}`;
    console.log(`Pedido informacion id = ${id} Url = ${url}`);
    //Creo un objeto request que servira como contenedor para enviar 'POST'
    //o resivir información 'GET' al servidor
    var objRequest = new XMLHttpRequest;
    //Al ejecutar se esta función intenta comunicarse hasta cuatro veces
    //con el servidor, la función se ejecutara tras cada llamado
    objRequest.onreadystatechange = function(){

        //Si logramos conectarnos con el servidor se ejecutara el código
        if(this.readyState == 4 && this.status == 200){
            var personaje = JSON.parse(this.responseText);
            console.log(`Hola yo soy, ${personaje.name}`);   
            //Una vez se ha ejecutado el código llamo el callback
            if(callback){
                callback();//El callback sera la opcion del reques y las demas funciones anidadas
            }                 
        }                 
    }
    //Defino el tipo de request como get, la url del servidor y que sera
    //una comunicación asincrona = true
    objRequest.open('GET', url, true);
    //Hago la petición 
    objRequest.send();
}

getInformation(1, function(){
    getInformation(3, function(){
        getInformation(4, function(){
            getInformation(5, function(){
                getInformation(' 2')
            })
        })
    })
})
//Con dos no funciona el request si no se deja un espacio(' 2')
//Pequeño reto a quien pueda corregir el fallo (-_-)
//getInformation("2")

Muy enriquecedor este curso tiene muchos topics interesantes. Hasta ahora 10/10

Creo que en el callback 3 ya lo había entendido xD

Haciendo uso de la recursividad, podemos hacer que la función de obtener personaje se llame a si misma, evitándonos el “callback hell”:

const API_URL = 'https://swapi.dev/api/';
const PEOPLE_URL = 'people/:id'

// var personNumber = prompt("What person do you want to meet?")
const OPTS =  { crossDomain: true };

function getCharecter(id) {
    const PERSON_URL = `${API_URL}${PEOPLE_URL.replace(':id', id)}`;

    $.get(PERSON_URL, OPTS, function(person) {

        console.log(`Hi!, I´m ${person.name} and my hair is ${person.hair_color }. My index is ${id}`);
        if(id <= 100){
            getCharecter(id+1);
        }
        
        
    });

}

getCharecter(1);

Es mi idea o esto no es otra cosa que recursividad?

Cuando intenté dejar la función dentro de la constante onPeopleResponse y allí invocar a callback, no me aparecían en orden los nombres de los personajes, pero cuando borré la constante y directamente puse la función dentro de los parámetros del $.get, recién funciono el orden de los personajes. ¿Alguien sabe a que se debe esto?, porque aparentemente sería lo mismo dejar la función dentro de una constante, que ponerla directamente.

yo mejoraria el algoritmo con un for


//id: 25 pikachu
const opts = { crossDomain: true };

function obtenerPersonajes(id, callback) {
  const url = `${API_URL}${POKEMON_URL.replace(":id", id)}`;

  $.get(url, opts, function (response) {
    console.log(
      `Hola yo soy el pokemon, ${response.name} soy un pokemon de tipo , 
    ${response.types[0].type.name}, mi peso es de  ${response.weight}
     y tengo dos habilidades, la primera es ${response.abilities[0].ability.name},
      y la segunda es ${response.abilities[1].ability.name},
       Esta es una impresión para todos hermosos seguidores de NODEJS.MDE `
    );
  });

  if (callback) {
    callback();
  }
}

for (let i = 0; i <= 25; i++) {
  obtenerPersonajes(i, function () {
    obtenerPersonajes(i + 1, function () {});
  });
}```

TENGO UNA DUDA:
Como puedo mantener la funcion ‘onPeopleResponse()’ de tal forma que le pase por parametro la data y el callback.
Pues trato de mantener esa función en el código y pasa dos errores:

  • me dice que el callback no esta definido, y no se como pasarle ese paramatro (eh intentado varias cosas y nada).
  • si invoco el callback luego de la linea $get.(url,opts,onPeopleResponse) el orden de los personajes no esta asegurado.

Ahora tengo un mejor entendimiento de lo que son las callbacks


const API_URL= 'https://swapi.co/api/'
const PEOPLE_URL= 'people/:id'
//meotodo $.get nos permite hacer un request  y puee recibir varios parametros
//const lukeUrl=`${API_URL}${PEOPLE_URL.replace(':id',1)}`
const opts={crossDomain: true}

//$.get(lukeUrl, opts, onPeopleResponse)

function obtenerPersonaje(id ,callback){
  const url= `${API_URL}${PEOPLE_URL.replace(':id',id)}`
  $.get(url, opts, function (persona){
    console.log(`Hola yo soy, ${persona.name}`)
  })
  if (callback){
    callback()
  }
}
obtenerPersonaje(1, function (){
    obtenerPersonaje(2, function (){
      obtenerPersonaje(3)
    })
})

Callback Hell

Si se continua escribiendo código con callbacks uno seguido de otro, el código se vuelve horizontal en lugar de vertical, además de no estár muy claro en donde termina cada uno de ellos, se vuelve inmantenible, literalmente un infierno de callbacks

Yo lo hice asi pero me sale un error

function obtenerPersonaje(id,callback){
  const url= `${api_url}${people_url.replace(':id',id)}`
  $.get(url,opts, function(person){
  console.log(`Hello, I'm ${person.name} `)
    if(callback){
      callback()
    }
})
}
//recorrer a unn for
for (i=1;i<=5;i++){
  obtenerPersonaje(i,function(){
    obtenerPersonaje(i+1)
  })
}

Debemos evitar el CallBack Hell como buena practica de desarrollador JavaScript.

Esta clase me bajoneo…

const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'
const opts = {crossDomain:true}
//agregando un parametro callback
function obtenerPersonaje(id, callback){
    const url = `${API_URL}${PEOPLE_URL.replace(':id',id)}`

    $.get(url,opts, function ({name}){
        console.log(`Hola, yo soy ${name}`)
        //llamando al calback
        if (callback){
            callback()
        }
    })
}
//llamando en orden las solicitudes de pedido
//Esto es llamado un infierno de callback al no saber donde
//terminan rapidamente
obtenerPersonaje(1, function(){
    obtenerPersonaje(2, function(){
        obtenerPersonaje(3, function(){
            obtenerPersonaje(4, function(){
                obtenerPersonaje(5, function(){
                    obtenerPersonaje(6, function(){
                        obtenerPersonaje(7)
                    })
                })
            })
        })  
    })
})
obtenerPersonaje(1, function() {
  obtenerPersonaje(2, function() {
    obtenerPersonaje(3, function() {
      obtenerPersonaje(4, function() {
        obtenerPersonaje(5)
      })

    })

  })

})```

esto hay que practicarlo mucho, porque es muuuuy denso…

APORTE DE RESUMEN DE LA CLASE

// RESUMEN DE LA CLASE : 'ORDEN Y ASINCRONISMO'
// - Tomaremos como referencia el codigo de la clase anterior
//
// - En la clase anterior hemos podido presenciar lo que es el
//   'Asincronismo en JavaScript' cuando hacemos 'requests'
//   (solicitudes), que a pesar de invocar a las funciones en el
//   orden que queremos que aparezcan, no siempre va a ser asi.
//
// - En esta clase lo que se quiere es que aparezcan en el orden
//   en la que se invoca la funcion. Para eso utilizaremos los
//   'Callbacks',pero esta vez ya no con 'setTimeout()' .

const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'
const Options = { crossDomain:true }

// - Primero, el cambio que hicimos es agregar y declarar un
//   segundo parametro cuyo nombre es 'callback'.
function obtenerPersonaje(id,callback) {
  const url = `${API_URL}${PEOPLE_URL.replace(':id',id)}`
// - Segundo, el cambio que hicimos fue que en vez declarar una variable que
//   contenga a la funcion anonima, la funcion anonima va declarada como 3er
//   parametro en el '$.get()'.
//
// - Ademas, dentro de la 'funcion anonima' se va a ejecutar un 'if' cuando
//   exista una funcion que se haya pasado como parametro.
  $.get(url,Options, function (persona) {
    console.log(`Hola, yo soy ${persona.name}`)

      if(callback){
        callback()
      }

  })
}

// - Que es lo que nos dice este codigo de invocacion:
//   "Se invoca la funcion 'obtenerPersonaje', cuyo primer parametro
//    es 1 y lo utiliza para traer el primer personaje de Star Wars.
//    Luego, utiliza el segunda parametro , que es una funcion, para
//    ver si existe o no , para poder ejecutar la funcion que contiene
//    a la misma funcion 'obtenerPersonaje' pero con parametro inicial 2
//    y asi sucesivamente."
obtenerPersonaje(1 ,function(){
  obtenerPersonaje(2,function () {
      obtenerPersonaje(3,function () {
          obtenerPersonaje(4,function () {
              obtenerPersonaje(5,function () {
                  obtenerPersonaje(6,function () {
                      obtenerPersonaje(7)
                  })
              })
          })
      })
  })
})
// - A esta forma de codigo que estamos haciendo se le denomina
//   callbackHell(Infierno de as devoluciones de llamada).

No es necesario pasar la función del OnPeopleResponse directamente… se pude mantener la consntante antes declarada.

const API_URL = 'http://swapi.dev/api/';
const PEOPLE_URL = 'people/:id';

//const lukeUrl = `${API_URL}${PEOPLE_URL.replace(':id',1)}`;

const opts = { crossDomain: true};// Esto algo propio de Jquery, para cuando se quiere referencia hacia otra web

const onPeopleResponse = function (personaObjetoAPI){
    console.log (`Mi Nombre es ${personaObjetoAPI.name}`);//name, es el nomre del atributo que se obtiene de la API
};
// Agregamos un parametro nuevo, que sera el call back
function obtenerPersonaje(id, callback) {
    const url = `${API_URL}${PEOPLE_URL.replace(':id',id)}`;
    console.log(id);
    // En el llamado, pasamos la funcion directamente
    $.get(url,opts,onPeopleResponse);
    // $.get(url,opts,function (personaObjetoAPI){
    //         console.log (`Mi Nombre es ${personaObjetoAPI.name}`);//name, es el nomre del atributo que se obtiene de la API
    //     });

        if (callback) {
            callback();
        }
}

// Se anidan las llamas y se les envia la funcion para que respete el callback
obtenerPersonaje(1, function (params) {
    obtenerPersonaje(2, function (params) {
        obtenerPersonaje(3, function (params) {
            obtenerPersonaje(4), function (params) {
                obtenerPersonaje(5);    
            };    
        });    
    });    
});
// obtenerPersonaje(2);
// obtenerPersonaje(5);
// obtenerPersonaje(6);
// obtenerPersonaje(10);```

Con un for

const API_URL = 'https://pokeapi.co/api/v2/';
const POKEMON_URL = 'pokemon/:id';
const opts = { crossDomain: true };

function obtenerPersonaje(id, callback){
    const url = `${API_URL}${POKEMON_URL.replace(':id',id)}`;
    
    $.get(url, opts, function (persona){
        console.log(`Hola, soy ${persona.name}`);

        if(callback){
            callback();
        }
    })
}

for(var i = 1; i < 10; i++){
    obtenerPersonaje(i, function(){
        obtenerPersonaje(i++);
    });
}

// obtenerPersonaje(1, function(){
//     obtenerPersonaje(2, function(){
//         obtenerPersonaje(3, function(){
//             obtenerPersonaje(4, function(){
//                 obtenerPersonaje(5, function(){
//                     obtenerPersonaje(6, function(){
//                         obtenerPersonaje(7);
//                     });
//                 });
//             });
//         });
//     });    
// });

Hecho con un for

<code>
var num = 1;

for(var i = 1; i <= 12; i++){
    function obtenerPersonajes(id, callback){
        const url = `${API_URL}${PEOPLE_URL.replace(":id", id)}`;
    
        $.get(url, opts, function(personaje){
            console.log("Hola yo soy " + personaje.name + " y nací el " + personaje.birth_year);
    
            if(callback){
                callback();
            }
        });
    
    };
    obtenerPersonajes(num, function (){});
    num++;
}

Reitero, con un live server, es mucho mas comodo.

The API’s are awesome

Este codigo funciona perfectamente, pero de donde sale el “persona” en function (persona)???

const URL_API = "https://swapi.co/api/";
const PEOPLE_URL = "people/:id";
const opts = { crossDomain: true };

function obtenerPersonaje(id, callback) {
  const url = `${URL_API}${PEOPLE_URL.replace(':id', id)}`;
  $.get(url, opts, function (persona) {        //Si hay success,
    console.log(`Hola yo soy ${persona.name}`)

    if (callback) { //Si existe la funcion, se activa la funcion.
      callback();
    }
  })
}

obtenerPersonaje(1, function () {
  obtenerPersonaje(2, function () {
    obtenerPersonaje(3, function () {
      obtenerPersonaje(4)
    })
  });
});```

porque me lo lista asi si esta en serio

cod:

Como seria si quisiera evaluar la llegada de los callback con un ciclo for para abreviar

Okey, sinceramente, siento que me excedí y me olvidé del simplismo. ¿Qué dicen?

// API settings
const API_URL = 'https://swapi.co/api/'
const COLLECTION_URL = 'people/'
const OPTS = { crossDomain: true }



// Global variables
var character_array = []
var user_response
var master = 0


// Magic Numbers~
const INITIAL_LIMIT = 1
const FINAL_LIMIT = 88
const YES = 1
const NO = 2



// Conditionals
const INCORRECT_CHARACTER_INPUT = user_response => user_response < INITIAL_LIMIT || user_response > FINAL_LIMIT
const INCORRECT_ADD_CHARACTER_INPUT = user_response => user_response < YES || user_response > NO
const MAIN_LOOP = user_response => user_response === 1



// Functions
const access_url = document_url => `${API_URL}${COLLECTION_URL}${document_url}`

const character_selection = () => {
  do{
    var user_response = prompt(`Selecciona un número del ${INITIAL_LIMIT} al ${FINAL_LIMIT}`)
    if (INCORRECT_CHARACTER_INPUT(user_response)){
      alert('Lo sentimos.\nEl número ingresado no se encuentra dentro de los límites estipulados.')
    }else{
      var url = access_url(user_response)
      window.character_array.push(url)
    }
  }while(INCORRECT_CHARACTER_INPUT(user_response))
}

const ADD_CHARACTER_INPUT = () =>  {
  do{
    user_response = prompt('¿Desearía agregar otro número?\n1: Sí\n2: No')
    user_response = parseInt(user_response)
    switch(user_response){
      case 1:
        break
      case 2:
        break
      default:
        alert('Por favor, ingrese un número dentro de los parámetros')
        user_response = 0
        break
    }
  }while(INCORRECT_ADD_CHARACTER_INPUT(user_response))
  return user_response
}

const character_print = (ARRAY_POS) => {
  $.get(ARRAY_POS, OPTS, function(character){
    console.log(`Hola, soy ${character.name}`)

      if (window.master < character_array.length-1){
          window.master ++
          character_print(character_array[window.master])
      }
  })
}



// Main
do{
character_selection()
user_response = ADD_CHARACTER_INPUT()
}while(MAIN_LOOP(user_response))

character_print(character_array[master])```

MANEJANDO EL ORDEN Y EL ASINCRONISMO EN JS

const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'

const opst = {crossDomain: true}


function obtenerUnaPersona (id, callback){
    const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`

    
    $.get(url, opst, function(person){
        console.log(`Hola, soy ${person.name}`)
        if(callback){
            callback()
        }
    }
    )
}

obtenerUnaPersona(1, function(){
    obtenerUnaPersona(2, function (){
        obtenerUnaPersona(3, function(){
            obtenerUnaPersona(4, function(){
                obtenerUnaPersona(5, function(){
                    obtenerUnaPersona(6, function(){
                        obtenerUnaPersona(7)
                    })
                })
            })
        })

    })

})

Aca lo importante es saber que en el callback al acomodarlo de esta manera enviara siempre esperara la respuesta del enviado, asi que envia, y solicita, envia y solicita, envia y solicita y asi, es lo que debemos llevarnos de esta clase, la menera en la que se puede manejar el orden de llegada de respuesta, cosa que haremos mejor en las promises.

const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'

const opst = {crossDomain: true}


function obtenerUnaPersona (id, callback){
    consturl = `${API_URL}${PEOPLE_URL.replace(':id', id)}`

    
    $.get(consturl, opst, function(person){
        console.log(`Hola, soy ${person.name}`)
        if(callback){
            callback()
        }
    }
    )
}

obtenerUnaPersona(1, function(){
    obtenerUnaPersona(2, function (){
        obtenerUnaPersona(3, function(){
            obtenerUnaPersona(4, function(){
                obtenerUnaPersona(5, function(){
                    obtenerUnaPersona(6, function(){
                        obtenerUnaPersona(7)
                    })
                })
            })
        })

    })

})

<code>

const cantidad = 4
for (var i =1; i < cantidad; i++){
	obtenerPersonaje(i, function(){
		obtenerPersonaje(i + 1)
	})
}

si no entendí mal, en este ejemplo hemos utilizados dos callbacks, el primero es el anónimo que se pasa como parmetro del get y que decide que hacer con el personaje devuelto por el get, y el segundo callback es el que se utilizó para definir que hacer al final de imprimir un personaje, que en este caso utilzamos para obtener el siguiente personaje.

const URL_DE_ACCESO = 'https://swapi.dev/api/'
const PEOPLE_URL = 'people/:id'

const OPTIONS = {crossDomain: true}

//Para ordenar el asíncronismo añadimos un segundo parámetro a la función añadiendo el callback
function obtenerPersonaje(id, callback){
	const URL_PERSONAJE = `${URL_DE_ACCESO}${PEOPLE_URL.replace(':id', id)}`
	$.get(URL_PERSONAJE, OPTIONS, function(person){
		console.log(`Hola, yo soy ${person.name}, mido ${person.height} cm`)

		if (callback){
			callback()
		}
	})
}

obtenerPersonaje(1, function(){
	obtenerPersonaje(2, function(){
		obtenerPersonaje(3, function(){
			obtenerPersonaje(4, function(){
				obtenerPersonaje(5, function(){
					obtenerPersonaje(6)
				})
			})
		})
	})
})
//Lo que se está haciendo aquí son peticiones en serie, a este código horizontal se le conoce como Callback Hell
const API_URL = 'https://pokeapi.co/api/v2/'
const POKEMON_URL = 'pokemon/:id'
const opts = { crossDomain: true }


function obtenerPokemon(id, callback){
  const url = `${API_URL}${POKEMON_URL.replace(':id', id)}`
  $.get(url, opts, function (pokemon){
    console.log(`Hola, soy ${pokemon.name}`)

    if (callback){
      callback()
    }
  })
}

  obtenerPokemon(1, function(){
    obtenerPokemon(2, function(){
      obtenerPokemon(3, function(){
        obtenerPokemon(4, function(){
          obtenerPokemon(5, function(){
            obtenerPokemon(6, function(){
              obtenerPokemon(7, function(){
                obtenerPokemon(8, function(){
                  obtenerPokemon(9, function(){
                    obtenerPokemon(10)
                  })
                })
              })
            })
          })
        })
      })
    })
  })

//clase 30 manejando el orden y el asincronismo en js
const API_URL = 'https://swapi.dev/api/'
const PEOPLE_URL = 'people/:id'
//metodo replace para reemplazar el string 
const opts = { crossDomain: true }// segundo parametro 
//1 agregamos dos arametros al metodo get
//pasamos una funcion como 3l 3 parametro
function obtenerPersonaje(id, callback) {
    const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`//primer parametro

    $.get(url, opts, function (personaje) {
        console.log(`Hola, yo soy ${personaje.name}`)
        if (callback) {
            callback()
        }
    })
}
obtenerPersonaje(1, function () {
    obtenerPersonaje(2, function () {
        obtenerPersonaje(3, function () {
            obtenerPersonaje(4, function () {
                obtenerPersonaje(5, function () {
                    obtenerPersonaje(6, function () {
                        obtenerPersonaje(7, function () {
                            obtenerPersonaje(8, function () {
                                obtenerPersonaje(9, function () {
                                    obtenerPersonaje(10, function () {
                                    })
                                })
                            })
                        })
                    })
                })
            })
        })
    }
    )
})```

Callback Hell, que buen nombre

Código de la clase con algunos apuntes

Medio complejo esos callbacks anidados

no me funciona, me sigue saliendo el orden que javascript quiere 😦

const apiUrl = "https://swapi.co/api/";

const peopleUrl = "people/id";

const paginaExterna = { crossDomain: true };

function personaje(id, callback) {
  const url = `${apiUrl}${peopleUrl.replace("id", id)}`;

  $.get(url, paginaExterna, function imprimir(character) {
    if (character.mass == "unknown") {
      character.mass = "desconocida";
    } else {
      character.mass = `${character.mass} kilograms`;
    }

    console.log(
      `I am the original ${character.name} and my mass is ${character.mass}`
    );
  });

  if (callback) {
    callback();
  }
};

personaje(1, function() {
  personaje(2, function() {
    personaje(3, function() {
      personaje(4);
    });
  });
});

Buen día a todos,
Tengo una consulta que nada tiene que ver con el curso.
Soy nuevo en Platzi y aun no entiendo del todo la dinámica de los puntos obtenidos a medida que avanzo con el aprendizaje, o para que sirven si es que sirven de algo.

Cualquier información al respecto será bien recibida y agradecida.

Disculpen si los importuno con este tipo de cuestiones por este medio.

Al agregar una función no garantiza nada el orden de llegada de respuesta que es aleatorio todavía, si queremos garantizar el orden debemos ir llamando las funciones de obtener los personajes, pero con esto perdemos el paralelismo, es decir lo hacemos en serie.

const API_URL = 'http://swapi.co/api/'
const PEOÇPLE_URL = ‘people/:id’

const opst = { crossDomain: true }

// funcion extra callback
function obtenerPersonaje(id,callback){
const url = ${API_URL}${PEOÇPLE_URL.replace(':id',id)}

$.get(url, opst, function ( dataLuke) {
console.log(hola, yo soy ${dataLuke.name} )
if(callback){
callback()
}
})
}

obtenerPersonaje(1, function (){
obtenerPersonaje(2, function (){
obtenerPersonaje(3, function(){
obtenerPersonaje(4, function(){
obtenerPersonaje(5)
})
})
})
})

Resumen Clase: No tenemos manera de obtener el mismo orden que pedimos una solicitud al servidor nos lleguen en el mismo orden las respuestas. La única manera es, si mantenemos ese mismo orden a lo largo del programa.

Madre mia Guilly.

// REQUEST
obtenerPersonaje(1, function(){
    obtenerPersonaje(2, function(){
        obtenerPersonaje(3, function(){
            obtenerPersonaje(4, function(){
                obtenerPersonaje(5, function(){
                    obtenerPersonaje(6, function(){
                        obtenerPersonaje(7, function(){
                            obtenerPersonaje(8);
                        });
                    });
                });
            });
        });
    });
});```
<clase30.js>
const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'
const opts =  {crossDomain: true}


function obtenerPersonaje(id, callback ){
    const url = `${API_URL}${PEOPLE_URL.replace(`:id`, id)}`

  $.get(url, opts,  function (persona){
  console.log(`Hola, yo soy ${persona.name}`)

  if(callback){
    callback()
  }
})
}

obtenerPersonaje(1, function(){
 obtenerPersonaje(2, function(){
    obtenerPersonaje(3, function(){
       obtenerPersonaje(4, function(){
         obtenerPersonaje(5, function(){
           obtenerPersonaje(6, function(){
             obtenerPersonaje(7, function(){
               obtenerPersonaje(8, function(){
                 obtenerPersonaje(7, function(){
                   obtenerPersonaje(8, function(){
                     obtenerPersonaje(9, function(){
                       obtenerPersonaje(10, function(){
                         obtenerPersonaje(11, function(){
                           obtenerPersonaje(12, function(){
                             obtenerPersonaje(13, function(){
                               obtenerPersonaje(14, function(){
                                 obtenerPersonaje(15, function(){
                                   obtenerPersonaje(16, function(){
                                     obtenerPersonaje(17, function(){
                                       obtenerPersonaje(18, function(){
                                         obtenerPersonaje(19, function(){
                                           obtenerPersonaje(20, function(){
                                             obtenerPersonaje(21, function(){
                                               obtenerPersonaje(22, function(){
                                                 obtenerPersonaje(23, function(){
                                                   obtenerPersonaje(24, function(){
                                                     obtenerPersonaje(25, function(){
                                                       obtenerPersonaje(26, function(){
                                                         obtenerPersonaje(27, function(){
                                                           obtenerPersonaje(28, function(){
                                                             obtenerPersonaje(30, function(){
                                                               obtenerPersonaje(31, function(){
                                                                 obtenerPersonaje(32, function(){
                                                                   obtenerPersonaje(33, function(){
                                                                     obtenerPersonaje(34, function(){
                                                                       obtenerPersonaje(35, function(){
                                                                         obtenerPersonaje(36, function(){
                                                                           obtenerPersonaje(37, function(){
                                                                             obtenerPersonaje(38, function(){
                                                                               obtenerPersonaje(39, function(){
                                                                                 obtenerPersonaje(40, function(){
                                                                                   obtenerPersonaje(41, function(){
                                                                                     obtenerPersonaje(42, function(){
                                                                                       obtenerPersonaje(43, function(){
                                                                                         obtenerPersonaje(44, function(){
                                                                                           obtenerPersonaje(45, function(){
                                                                                             obtenerPersonaje(46, function(){
                                                                                               obtenerPersonaje(47, function(){
                                                                                                 obtenerPersonaje(48, function(){
                                                                                                   obtenerPersonaje(49, function(){
                                                                                                     obtenerPersonaje(50, function(){
                                                                                                       obtenerPersonaje(51, function(){
                                                                                                         obtenerPersonaje(52, function(){
                                                                                                           obtenerPersonaje(53, function(){
                                                                                                             obtenerPersonaje(54, function(){
                                                                                                               obtenerPersonaje(55, function(){
                                                                                                                 obtenerPersonaje(56, function(){
                                                                                                                   obtenerPersonaje(57, function(){
                                                                                                                     obtenerPersonaje(58, function(){
                                                                                                                       obtenerPersonaje(59, function(){
                                                                                                                         obtenerPersonaje(60, function(){
                                                                                                                           obtenerPersonaje(61, function(){
                                                                                                                             obtenerPersonaje(62, function(){
                                                                                                                               obtenerPersonaje(63, function(){
                                                                                                                                 obtenerPersonaje(64, function(){
                                                                                                                                   obtenerPersonaje(65, function(){
                                                                                                                                     obtenerPersonaje(66, function(){
                                                                                                                                       obtenerPersonaje(67, function(){
                                                                                                                                         obtenerPersonaje(68, function(){
                                                                                                                                           obtenerPersonaje(69, function(){
                                                                                                                                             obtenerPersonaje(70, function(){
                                                                                                                                               obtenerPersonaje(71, function(){
                                                                                                                                                 obtenerPersonaje(72, function(){
                                                                                                                                                   obtenerPersonaje(73, function(){
                                                                                                                                                     obtenerPersonaje(74, function(){
                                                                                                                                                       obtenerPersonaje(75, function(){
                                                                                                                                                         obtenerPersonaje(76, function(){
                                                                                                                                                           obtenerPersonaje(77, function(){
                                                                                                                                                             obtenerPersonaje(78, function(){
                                                                                                                                                               obtenerPersonaje(79, function(){
                                                                                                                                                                 obtenerPersonaje(80, function(){
                                                                                                                                                                   obtenerPersonaje(81, function(){
                                                                                                                                                                     obtenerPersonaje(82, function(){
                                                                                                                                                                       obtenerPersonaje(83, function(){
                                                                                                                                                                         obtenerPersonaje(84, function(){
          obtenerPersonaje(85)

        })
      })
    })
  })
})
})
})
})        })
      })
    })
  })        })
        })
      })
    })        })
          })
        })
      })        })
            })
          })
        })        })
              })
            })
          })        })
                })
              })
            })        })
                  })
                })
              })        })
                    })
                  })
                })        })
                      })
                    })
                  })        })
                        })
                      })
                    })        })
                          })
                        })
                      })        })
                            })
                          })
                        })        })
                              })
                            })
                          })        })
                                })
                              })
                            })

                          })
                               })
                             })
                           }) })
                                 })
                               })
                             }) })
                                   })
                                 })
                               }) })
                                     })
                                   })
                                 }) })
                            })
                          })
                          })
                          })

El orden de impresión se asegura dado a que las solicitudes (CallBacks) se envían a la cola de tareas y se ejecutan en el orden en que muestra la estructura:

obtenerPesonaje(1, function(personaje){
console.log(Hola, soy ${personaje.name})

obtenerPesonaje(2, function(personaje){
    console.log(`Hola, soy ${personaje.name}`)
    
    obtenerPesonaje(3, function(personaje){
        console.log(`Hola, soy ${personaje.name}`)
    })
    
})

})

aca me quedo mas claro el tema de los callback

const API_URL = 'https://swapi.co/api/'
const PEOPLE_URL = 'people/:id'

function obtenerPersonaje(id, callback) {
  const PERSONAJE_URL = `${API_URL}${PEOPLE_URL.replace(':id', id)}`
  var req = new XMLHttpRequest()
  req.open('GET', PERSONAJE_URL, true)
  req.onreadystatechange = function () {
    if (req.readyState == 4) {
     if(req.status == 200) {
      var person = JSON.parse(this.responseText)
      console.log( `Hola yo soy ${person.name}`)
      } else {
        console.log('Ocurrió un error\n')
      }
      if (callback)
        callback()
    }
    
  }
  req.send(null)
} 
obtenerPersonaje(1,function() {
  obtenerPersonaje(2, function(){
    obtenerPersonaje(3, function() {
      obtenerPersonaje(4, function(){
        obtenerPersonaje(5)
      })
    })
  })
})

qué es lo de crossDomain?

Importante que el if(callback) este dentro del $.get (), sino no funciona.
La verdad no lo comprendí muy bien internamente viendo como el navegador va desarrollando linea por linea, por que es mas o menos lo mismo, trae todo, y después tira todo, pero no se por que hace que en la segunda forma de hacerlo lo tira de forma ordenada.

Wuuuaoo, esto si me interesa, está genial!! Gracias!!

callback hell " CALLBACK INFIERNO"

Y si ponemo el callback dentro de un for?

Como funciona el callback al llamarlo con callback() estariamos corriendo el segundo parametro de obtener personaje??

const API_URL = "https://swapi.co/api/";
const PEOPLE_URL = "people/:id";
const opts = { crossDomain: true };

function obtener_personaje(id, callback) {
	const url = `${API_URL}${PEOPLE_URL.replace(":id", id)}`;
	$.get(url, opts, function(persona) {
		console.log(`Hola yo soy ${persona.name}`);
		if (callback) {
			callback();
		}
	});
}

obtener_personaje(1, function() {
	obtener_personaje(2, function() {
		obtener_personaje(3, function() {
			obtener_personaje(4, function() {
				obtener_personaje(5, function() {
					obtener_personaje(6);
				});
			});
		});
	});
});
const API_URL='https://swapi.co/api/';
const PEOPLE_URL ='people/:id';

const opts = { crossDomain: true};

function obtenerPersonaje(id, callback){
    const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`;
    $.get(url, opts, (data)=> console.log(`Hola, yo soy ${data.name}`));
    if(callback){
        callback();
    }
}

obtenerPersonaje(1, ()=>obtenerPersonaje(2,()=>obtenerPersonaje(3)));




Muy buena clase, la verdad anteriormente estuve investigando lo de callbacks y la verdad no le entendía nada.

Pero ahora con la explicación y el ejercicio me quedo más claro. Muchas gracias y comparto mi código.

//exelente, ahora toca ver como mejorar ese anidamiento o mejor como evitar el Callback Hell
//aqui mi codigo de la clase

const API_URL = “https://swapi.dev/api/”;
const PEOPLE_URL = ‘people/:id’;

//const lukeUrl = ${API_URL}${PEOPLE_URL.replace(':id', 1)};
const opts= {crossDomain: true};

//const onPeopleResponse =

//$.get(lukeUrl,opts, onPeopleResponse);

function obtenerPersonaje(id, CallBack) {
const url= ${API_URL}${PEOPLE_URL.replace(':id', id)};

$.get(url,opts, function (persona) {
console.log(Hola, soy ${persona.name});

if (CallBack){
  CallBack();
}

});
};

/*
for (var i = 1; i < 20; i++) {
// += i;
obtenerPersonaje(i);

}
*/

obtenerPersonaje(1, function(){
obtenerPersonaje(2, function(){
obtenerPersonaje(3, function(){
obtenerPersonaje(4,function(){
obtenerPersonaje(5,function(){
obtenerPersonaje(6,function(){
obtenerPersonaje(7);
});
});
});
});
});
});

Buena explicacion.

Callback Hell xD

interesante !

La única manera de darle orden a los datos recibidos del server por callback es...

Cómo escribir y garantizar el correcto orden de impresión de los datos llamados por callback desde el server

Causa un lio visual el callbackHELL O.O

Aunque este método ya no es muy usado, lo entendí bien y creo que es fácil de usar, y creo que sería muy útil, al menos cuando no hay tantos anidados.

¿Saben que significa este error? Me pasa cuando hago un for:

const API_URL = "https://swapi.co/api/";
const PEOPLE_URL = "people/:id";
const opts = {crossDomain: true};

function obtenerPersonajes(id){const url = `${API_URL}${PEOPLE_URL.replace(":id", id)}`
  $.get(url, opts, onResponse);}

const onResponse = function mostrarDatos(character){console.log(`Hola yo soy ${character.name}`)}


for (i = 0; i < 3; i++) {
obtenerPersonajes(i)
}

No pensaba que la solución fuera sencilla (relativamente), es increíble pero ese Callback Hell está de susto

Callback Hell!! jaja

Por fin, ya pude entender los callbacks! Excelente maestro 😄

No se que sea pero el modo normal o con arrows.

obtenerPersonaje(1,()=>obtenerPersonaje(2,()=>obtenerPersonaje(3 ,()=>obtenerPersonaje(4,()=>obtenerPersonaje(5,()=>obtenerPersonaje(6,()=>obtenerPersonaje(7)))))))```

Bueno, acá improvisé una forma de hacer que nuestro código sea un choclo gigante horizontal, espero que les sirva 😃

const API_URL = 'https://pokeapi.co/api/v2/';
const PEOPLE_URL = 'pokemon/:id';

// const pikachuUrl = `${API_URL}${PEOPLE_URL.replace(':id', 3)}`

const options = { crossDomain: true }

// const onResponse = function(pokemon) {
//     console.log('Pikachu: Pika pikaaa pikaaaachuuuuu');
//     console.log(`Pokedex ${pokemon.name} ${pokemon.game_indices[0].game_index}
//     es un pokemon de tipo ${pokemon.types[0].type.name}, 
//     mide ${pokemon.height*10} centimetros, 
//     su habilidad primaria es ${pokemon.abilities[0].ability.name}`)
// }

function obtenerCriatura(id, callback) {
    const url = `${API_URL}${PEOPLE_URL.replace(':id', id)}`
    $.get(url, options, function(pokemon) {
        console.log('Pikachu: Pika pikaaa pikaaaachuuuuu');
        console.log(`Pokedex ${pokemon.name} ${pokemon.game_indices[0].game_index}
        es un pokemon de tipo ${pokemon.types[0].type.name}, 
        mide ${pokemon.height*10} centimetros, 
        su habilidad primaria es ${pokemon.abilities[0].ability.name}`)

        if (callback) {
            callback();
        }
    })
}

//este tipo de llamado de las funciones es en serie, ya que no se ejecuta la siguiente funcion hasta que la anterior no este completada.
//conocido como (callbak hell) infierno de los call back. 
//esto termina siendo un problema en la escritura del codigo.

obtenerCriatura(1, function(){
    obtenerCriatura(2, function() {
        obtenerCriatura(3, function() {
            obtenerCriatura(4, function() {
                obtenerCriatura(5, function() {
                    obtenerCriatura(6, function() {
                        obtenerCriatura(7, function() {
                            obtenerCriatura(8 , function() {
                                obtenerCriatura(9, function() {
                                    obtenerCriatura(10, function() {
                                        obtenerCriatura(11)
                                    })
                                })
                            })
                        })
                    })
                })
            })
        })
    })
});

Buena clase, es bueno saber qué no hacer, y qué se puede mejorar en el código, estaré atenta a la siguiente clase 😃

muy buen ejercicio, excelente clase.

Definitivamente es un infierno. 😄

Para evitar que ese desorden que teniamos en la clase anterior debido al paralelismo que se tiene al enviar los callbacks, se postula esta tecnica de anniadir un segundo parametro (una funcion), para que asi tras realizarse el primer request y haberse finalizado, le continuen el resto de request, asi sucesicamente las veces que queramos.
Esto va a probocar un codigo voluminoso, por lo que va hacer dificil su manejo a nivel visual si se desea modificar un parametro.

const API_URL = "https://swapi.dev/api/";
const PEOPLE_URL = "people/:id";
const opt = { crossDomain: true };


function obtenerPersonaje(id, callback) {
  const url = `${API_URL}${PEOPLE_URL.replace(":id", id)}`;
  
  $.get(url, opt, function (person) {
    console.log(`Hola, yo soy ${person.name}`)
    
    if (callback) {
      callback()
    }
  })
}

obtenerPersonaje(1, function () {
  obtenerPersonaje(2, function () {
    obtenerPersonaje(3, function() {
      obtenerPersonaje(4, function () {
        obtenerPersonaje(5, function () {
          obtenerPersonaje(6, function () {
            obtenerPersonaje(7)
          })
        })
      })
    })
  })
})```

Sólo una vez he necesitado hacer algo como ésto, gracias a Dios 😂😂😂

No conocia este tema, sin saber ya habia trabajado con asincronismo async await…

Siguiendo el ejemplo del ejercicio, si quisiéramos meter la obtención de personajes dentro de un bucle while(por ejemplo, para que obtenga personajes mientras haya personajes), ¿sería necesario el uso de promesas?¿o cómo se haría ese bucle, si al ser la función de obtener asíncrona, nunca actualiza el valor de la condición, y nunca termina?