Las promesas de ES6

facebook-svg gplus-svg twitter-svg

En el presente las promesas de ES6 están soportadas en todos los navegadores modernos, excepto IE y Opera mini.

El soporte de Promises en los navegadores

Un polyfill

Ya que las promesas de ES6 no están soportadas en IE es posible que sea necesario utilizar un polyfill, como por ejemplo ES6-Promise

¿Que es una promesa?

Una promesa es algo que pasará en el futuro pero no inmediatamente. Por ejemplo una imagen que todavía no está cargada, pero cumple todos los requisitos necesarios así sea, y que en un futuro lo estará. Si queremos que una parte del código se ejecute solo cuando la imagen esté cargada, podemos utilizar promesas.

La sintaxis de una promesa

Para entender de que va, veamos un ejemplo en concreto: un precargador ( preloader ) de imágenes.


function cargarImagen(url) {
  // devuelve un nuevo objeto Promise
    return new Promise((cumplida, denegada) => {
      //El código que tiene que ejecutarse asíncronamente:
      let img = new Image();
      // llama la función cumplida() si la promesa está solucionada
      img.onload = () => {
        cumplida(url);
      };
       // llama la función denegada() en caso de error
      img.onerror = () => {
        denegada(url);
      };
      img.src = url;
    });
  }

Si sacamos esta función en consola. . .

let url = https://ruta/hacia/la/imagen.jpg;
console.log(cargarImagen(url))

Conseguimos algo así:

Promise {<pending>}__proto__: 
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: https://ruta/hacia/la/imagen.jpg

El estado [[PromiseStatus]] de una nueva promesa puede ser: "rejected" (denegada), "pending" (pendiente), o "resolved" (solucionada).

Cómo utilizar una promesa. El método then()

Si hay una promesa, entonces ( then ) el método then() llama una función que contiene lo que queremos que pase en este caso. Si no hay promesa el método then() llama otra función con lo que queremos que pase en caso de error. Algo así:

promesa.then(exito,error)

Utilizando la función cargarImagen() del ejemplo anterior podemos escribir:


cargarImagen(url).then(
   url => {
   //si hay éxito haz algo con este url
   contenedor.innerHTML = "<img src="'+url+'" alt = 'lo que fuera' />";
   }),
   error => {
   // si hay error haz otra cosa ( sácalo en consola )
   console.log("Error " + error);
};

Cargar varias imágenes

Primero definimos la ruta ( la carpeta donde se encuentran guardadas las imágenes ) y el array de las imágenes:


let ruta = "https://ruta/hacia/la/imagen/";
  // el array de las imagenes
  let imagenes = [
    "imagen1.jpg",
    "imagen2.jpg",
    "imagen3.jpg",
    "imagen4.jpg",
  ];

Después definimos el array de los contenedores. Dentro de cada .contenedor habrá una imagen. Y para que sea un array de verdad utilizamos el método Array.from()


  // el array de los contenedores
  let contenedores = Array.from(document.querySelectorAll(".contenedor"));

A continuación podemos poner cada imágen en su contenedor


imagenes.map((img ,index)=> {
  cargarImagen(ruta + img).then(
    url => {// en este caso url = ruta + img
    //si hay éxito haz algo con este url
    contenedores[index].innerHTML = "<img width="150" src="'+url+'" alt = 'lo que fuera' />"   
    }),
    error => {
    // si hay error sácalo en consola
    console.log("Error " + error);
    };
  });

Vea este ejemplo en Codepen

See the Pen preload images by Gabi (@enxaneta) on CodePen.