Promesas y manejo de asincronia en JAVASCRIPT

Las PROMESAS en JAVASCRIPT son una nueva característica incluida desde el estándar ECMA script 2015 que permite posponer una acción hasta que otra aya terminado de una manera positiva o negativa.  Lo que viene de maravilla a la hora de manejar acciones asíncronas con esta nueva tecnología.

Técnicamente una promesa es un objeto que representa un estado intermedio de una operación, y como su popio nombre lo indica... es una promesa de que en algún punto del futuro se devolverá  un resultado de algún tipo; No hay garantía de cuando pero si de que cuando el resultado este disponible o la promesa falle, el código proporcionado se ejecutará.

Después de esta pequeña intro veamos como es que funcionan las promesas de una buena vez; Comencemos con su sintaxis...

new Promise(function(resolve,reject){})

Se instancia un objeto Promise que recibe una función (que será ejecutada inmediatamente después de la implementación de la promesa) dicha función recibe un par de parámetros resolve y reject, los cuales son funciones que son llamadas para resolver o rechazar la promesa según sea el caso. 

Para comprender mejor su funcionamiento veamos como sería una implementación real con una petición ajax, observemos el siguiente código.


let promesa = new Promise((resolve,reject)=>{                           
    let request = new XMLHttpRequest();                                            
    request.open('GET','https://jsonplaceholder.typicode.com/todos/1');                                                                      
                                                                                                                                                      
    request.onload = () =>{                                                                                                                  
      if(request.status ==  200)                                                                                                                      
        resolve(JSON.parse(request.response));                                           
      else                                                                                                             
        reject();                                                                                                      
    }                                                                                                                  
                                                                                                                       
    request.send();                                                       
  }); 

  En el código anterior asignamos a nuestra variable promesa el resultado de nuestro objeto Promise, dentro de la función que pasamos al objeto  hacemos una petición de tipo GET hacia  https://jsonplaceholder.typicode.com/todos/1. Si la respuesta de la petición es exitosa, es decir, con un código 200, ejecutamos la función resolve() que retorna  la respuesta de la petición parseada a JSON. De lo contrario se ejecuta la función reject() que rechaza la promesa.

Aja!! y si ahora imprimimos la variable promesa para ver lo que nos retornó la petición...

console.log( promesa );

Vemos que nos imprime un objeto Promise con un estatus pendiente...


    Promise {}
      __proto__: Promise
      [[PromiseState]]: "fulfilled"
      [[PromiseResult]]: Object
      

¿Porqué pasa esto?¿Cómo vemos lo que la petición nos retornó?

Recordemos el término asincronia, la petición tarda una fracción de tiempo en responder por lo que hay un pequeño desface en el tiempo de ejecución de nuestro código. Entonces... ¿Qué hacemos? ¿Cómo extraemos los datos? Es aquí donde aparecen un par de métodos del objeto Promise...


promesa.then(r=>console.log(r))                                                      
    .catch(()=>console.log('Algo salió mal'));

El método then() define lo que se hará cuando la promesa sea resuelta y el método catch() para cuando nuestra promesa sea rechazada. Entonces obtendremos la siguiente salida...


  {userId: 1, id: 1, title: "delectus aut autem", completed: false}
    completed: false
    id: 1
    title: "delectus aut autem"
    userId: 1
  __proto__: Object

Comprendiendo esto será más fácil entender que hay  detrás de  las librerías basadas en promesas como axios o  la api fetch de javascript.