Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

unidades:06_promesas:03_avanzado [2014/08/26 19:38]
admin [Objeto con promesas]
unidades:06_promesas:03_avanzado [2014/09/02 00:16] (actual)
admin
Línea 1: Línea 1:
 ====== 6.3 Promesas avanzadas ====== ====== 6.3 Promesas avanzadas ======
-Acabamos de ver como funcionan las promesas. Para muchas aplicaciones ​son solo eso será necesario sin embargo AngularJS proporciona más métodos que nos pueden ser útiles en ciertos casos. Pasemos ahora a ver mas funcionalidades de las promesas.+Acabamos de ver cómo funcionan las promesas. Para muchas aplicaciones ​ será necesario ​sólo lo que acabamos de ver, sin embargoAngularJS proporciona más métodos que nos pueden ser útiles en ciertos casos. Pasemos ahora a ver mas funcionalidades de las promesas.
  
 Lo primero que vamos a hacer es actualizar el diagrama de clases de UML para reflejar todos los nuevos métodos que vamos a explicar. Lo primero que vamos a hacer es actualizar el diagrama de clases de UML para reflejar todos los nuevos métodos que vamos a explicar.
Línea 56: Línea 56:
 </​uml>​ </​uml>​
  
-Vemos ahora que se puede llamar a ''​defered.notify()''​ todas las veces que se quiera ​que la promesa seguirá en el estado ''​Pendiente''​.+Vemos ahora que se puede llamar a ''​defered.notify()''​ todas las veces que se quiera ​la promesa seguirá en el estado ''​Pendiente''​.
  
 <note tip> <note tip>
-No es posible llamar a ''​defered.notify()''​ una vez se haya resuelto la promesa pero tampoco antes de que se llame al método ''​promise.then''​.Esto último implica que no se puede llamar dentro de la función antes de retornar el objeto de la clase ''​Promise''​.+No es posible llamar a ''​defered.notify()''​ una vez se haya resuelto la promesa pero tampoco antes de que se llame al método ''​promise.then''​.Ésto último implica que no se puede llamar dentro de la función antes de retornar el objeto de la clase ''​Promise''​.
 </​note>​ </​note>​
  
Línea 121: Línea 121:
 </​sxh>​ </​sxh>​
  
-  * Lineas 6,7 y 8: Se ha puesto un timeout para que al pasar un milisegundo se notifique que vamos por el 0% ((Esto se hace ya que no se puede llamar a ''​notify''​ antes de retornar el objeto de la clase ''​Promise''​)). +  * Lineas 6,7 y 8: Se ha puesto un timeout para que al pasar un milisegundo se notifique que vamos por el 0% ((ésto se hace ya que no se puede llamar a ''​notify''​ antes de retornar el objeto de la clase ''​Promise''​)). 
-  * Líneas 9,10 y 11: Se notifica que vamos por el 33% al pasar 1000 ms +  * Líneas 9,10 y 11: Se notifica que vamos por el 33% al pasar 1000 ms. 
-  * Líneas 12,13 y 14: Se notifica que vamos por el 66% al pasar 2000 ms +  * Líneas 12,13 y 14: Se notifica que vamos por el 66% al pasar 2000 ms. 
-  * Línea 19: Ya hemos acabado los cálculos y notificamos que vamos por el 100%. Recuerda que esta línea hay que ponerla antes de ''​defered.resolve''​ ya que sino nunca se notificaría.+  * Línea 19: Ya hemos acabado los cálculos y notificamos que vamos por el 100%. Recuerda que esta línea hay que ponerla antes de ''​defered.resolve''​ ya que, de lo contrario, ​nunca se notificaría.
   * Líneas 34 y 35: Se añade la tercera función al método ''​then''​ la cual será llamada cada vez que nos notifiquen algo sobre el progreso de la operación. En este caso añadimos el carácter "​%"​ y lo ponemos en el ''​%scope''​ para que se muestre en la página HTML.   * Líneas 34 y 35: Se añade la tercera función al método ''​then''​ la cual será llamada cada vez que nos notifiquen algo sobre el progreso de la operación. En este caso añadimos el carácter "​%"​ y lo ponemos en el ''​%scope''​ para que se muestre en la página HTML.
  
Línea 130: Línea 130:
 Hay veces que nos interesa que se ejecute un código cuando se resuelve la promesa independientemente de si ha sido resuelta o rechazada. Para ello la clase ''​Promise''​ dispone de un método llamado ''​finally''​ que acepta como argumento una función de //​callback//​. Esta función de //​callback//​ se llamará justo antes de llamar a las funciones definidas en el método ''​then''​. Hay veces que nos interesa que se ejecute un código cuando se resuelve la promesa independientemente de si ha sido resuelta o rechazada. Para ello la clase ''​Promise''​ dispone de un método llamado ''​finally''​ que acepta como argumento una función de //​callback//​. Esta función de //​callback//​ se llamará justo antes de llamar a las funciones definidas en el método ''​then''​.
  
-Debido a que el método se llama ''​finally''​ y eso es una palabra reservada en javaScript, puede que el navegador no te deje llamarla directamente así que se deberá llamar usando la siguiente forma:+Debido a que el método se llama ''​finally''​ y ésta es una palabra reservada en javaScript, puede que el navegador no te deje llamarla directamente así que se deberá llamar usando la siguiente forma:
  
 <sxh js;​highlight:​ [2]> <sxh js;​highlight:​ [2]>
     promise["​finally"​](function() {     promise["​finally"​](function() {
-        alert("​Mensaje del ejemplo.Esto se llama justo antes de resolver o rechazar la promesa:"​);​+        alert("​Mensaje del ejemplo.Ésto se llama justo antes de resolver o rechazar la promesa:"​);​
     });     });
 </​sxh>​ </​sxh>​
Línea 142: Línea 142:
  
 ===== Hacer una promesa de un valor ===== ===== Hacer una promesa de un valor =====
-Otro caso que puede ocurrir es que la función a la que llamamos en vez de tener que calcular asíncronamente el resultado ya lo tenga disposible. Un caso muy típico ​en una llamada ''​$http''​ en el que el resultado está cacheado, en ese caso no tendría sentido usar una promesa ​ya que ya tenemos el resultado en el momento de llamar a la función. Sin embargo como el interfaz de nuestra función no lo podemos modificar , es necesario seguir usando una promesa.+Otro caso que puede ocurrir es que la función a la que llamamos en vez de tener que calcular asíncronamente el resultado ya lo tenga disposible. Un caso muy típico ​es una llamada ''​$http''​ en el que el resultado está cacheado. En ese caso no tendría sentido usar una promesa ​puesto ​que ya tenemos el resultado en el momento de llamar a la función. Sin embargocomo el interfaz de nuestra función no lo podemos modificar , es necesario seguir usando una promesa.
  
-Para estos casos AngularJS ​no ofrece el método ''​$q.when''​ que permite transforma cualquier valor en una promesa.+Para estos casos AngularJS ofrece el método ''​$q.when''​ que permite transforma cualquier valor en una promesa.
  
-Siguiendo ​no nuestro ejemplo hemos modificado la función ''​sumaAsincrona''​ para que cuando ambos argumentos son cero, no sea necesaria ​hacer el "​calculo"​ sino directamente retornamos el cero.+Siguiendo nuestro ejemplo hemos modificado la función ''​sumaAsincrona''​ para que cuando ambos argumentos son cero, no sea necesario ​hacer el "​calculo"​ sino directamente retornamos el cero.
  
 <sxh js;​highlight:​ [2]> <sxh js;​highlight:​ [2]>
Línea 154: Línea 154:
 </​sxh>​ </​sxh>​
  
-  * Línea 2: Retornamos una promesa cuyo resultado ya es el cero.+  * Línea 2: Retornamos una promesa cuyo resultado ya es cero.
  
 ===== Promesas en paralelo ===== ===== Promesas en paralelo =====
Línea 164: Línea 164:
  
 ==== Array de promesas ==== ==== Array de promesas ====
-Lo que hacemos es obtener todas las promesas y añadirlas todas a un array. Entonces llamamos al método ''​$q.all(array)''​ y le pasamos el array que contiene todas las promesas. Este método nos retornará la promesa unificada la cual solo se resolverá si todas se resuelven. Si alguna de las promesas iniciales es rechazada, la promesa unificada también será rechazada.+Lo que hacemos es obtener todas las promesas y añadirlas todas a un array. Entonces llamamos al método ''​$q.all(array)''​ y le pasamos el array que contiene todas las promesas. Este método nos retornará la promesa unificadala cual sólo se resolverá si todas se resuelven. Si alguna de las promesas iniciales es rechazada, la promesa unificada también será rechazada.
  
 Al haber varias promesas la forma de funcionar cambia de la siguiente forma: Al haber varias promesas la forma de funcionar cambia de la siguiente forma:
   * Al resolver la promesa, el parámetro es un array con cada uno de los valores.   * Al resolver la promesa, el parámetro es un array con cada uno de los valores.
-  * Si alguna de las promesas iniciales es rechazada , a la promesa unificada ​solo le llega un único rechazo que será el de la primera promesa que haya sido rechazada. El resto de los rechazos no se notificarán.+  * Si alguna de las promesas iniciales es rechazada , a la promesa unificada ​sólo le llega un único rechazo que será el de la primera promesa que haya sido rechazada. El resto de los rechazos no se notificarán.
   * No se generan mensajes de notificación en la promesa unificada.   * No se generan mensajes de notificación en la promesa unificada.
   * Si alguno de los elementos del array de promesas no es una promesa , entonces se llamará a ''​$q.when''​ para transformar el valor en una promesa.   * Si alguno de los elementos del array de promesas no es una promesa , entonces se llamará a ''​$q.when''​ para transformar el valor en una promesa.
  
-En el siguiente ejemplo podemos ver como se unifican varias promesas en una sola usando un array:+En el siguiente ejemplo podemos ver cómo se unifican varias promesas en una sóla usando un array:
  
 <sxh js;​highlight:​ [2,​5,​7,​9]>​ <sxh js;​highlight:​ [2,​5,​7,​9]>​
Línea 193: Línea 193:
  
 ==== Objeto con promesas ==== ==== Objeto con promesas ====
-Lo que hacemos es obtener todas las promesas y añadirlas todas a un objeto, donde cada propiedad del objeto debe ser una promesa. Entonces llamamos al método ''​$q.all(objeto)''​ y le pasamos el objeto que contiene las promesas. Este método nos retornará la promesa unificada la cual solo se resolverá si todas se resuelven. Si alguna de las promesas iniciales es rechazada, la promesa unificada también será rechazada.+Lo que hacemos es obtener todas las promesas y añadirlas todas a un objeto, donde cada propiedad del objeto debe ser una promesa. Entonces llamamos al método ''​$q.all(objeto)''​ y le pasamos el objeto que contiene las promesas. Este método nos retornará la promesa unificada la cual sólo se resolverá si todas se resuelven. Si alguna de las promesas iniciales es rechazada, la promesa unificada también será rechazada.
  
 Al haber varias promesas la forma de funcionar cambia de la siguiente forma: Al haber varias promesas la forma de funcionar cambia de la siguiente forma:
   * Al resolver la promesa, el parámetro es un objeto cuyas propiedades son cada uno de los valores.   * Al resolver la promesa, el parámetro es un objeto cuyas propiedades son cada uno de los valores.
-  * Si alguna de las promesas iniciales es rechazada , a la promesa unificada ​solo le llega un único rechazo que será el de la primera promesa que haya sido rechazada. El resto de los rechazos no se notificarán.+  * Si alguna de las promesas iniciales es rechazada , a la promesa unificada ​sólo le llega un único rechazoque será el de la primera promesa que haya sido rechazada. El resto de los rechazos no se notificarán.
   * No se generan mensajes de notificación en la promesa unificada.   * No se generan mensajes de notificación en la promesa unificada.
-  * Si alguno ​de las propiedades del objeto de promesas no es una promesa , entonces se llamará a ''​$q.when''​ para transformar el valor en una promesa.+  * Si alguna ​de las propiedades del objeto de promesas no es una promesa , entonces se llamará a ''​$q.when''​ para transformar el valor en una promesa.
  
-En el siguiente ejemplo podemos ver como se unifican varias promesas en una sola usando un objeto:+En el siguiente ejemplo podemos ver cómo se unifican varias promesas en una sola usando un objeto:
  
 <sxh js;​highlight:​ [2,​9,​11,​13]>​ <sxh js;​highlight:​ [2,​9,​11,​13]>​
Línea 222: Línea 222:
   * Línea 2: Creamos una nueva promesa llamada ''​mensajeMultipleObjetos ''​ que es la unión de las 3 promesas. Cada promesa es un propiedad del objeto que hemos creado.   * Línea 2: Creamos una nueva promesa llamada ''​mensajeMultipleObjetos ''​ que es la unión de las 3 promesas. Cada promesa es un propiedad del objeto que hemos creado.
   * Línea 9: El argumento ''​resultado''​ es un **objeto** con los 3 resultados de las 3 promesas. Cada propiedad coincide con el nombre de la propiedad del objeto que contenía las promesas.   * Línea 9: El argumento ''​resultado''​ es un **objeto** con los 3 resultados de las 3 promesas. Cada propiedad coincide con el nombre de la propiedad del objeto que contenía las promesas.
-  * Línea 11: Solo será llamado una única vez para la primera promesa que sea rechazada.+  * Línea 11: Sólo será llamado una única vez para la primera promesa que sea rechazada.
   * Línea 13: Nunca se llamará a este código ya que nunca se notifica nada en las promesas múltiples.   * Línea 13: Nunca se llamará a este código ya que nunca se notifica nada en las promesas múltiples.
  
Línea 229: Línea 229:
 </​note>​ </​note>​
 ===== Promesas encadenadas ===== ===== Promesas encadenadas =====
-El último tema que queda por ver es la posibilidad de encadenar resultados de promesas.Como vimos al principio de esta unidad es lo mas importante de las promesas ya que permite evitar la //pirámide de la muerte//.+El último tema que queda por ver es la posibilidad de encadenar resultados de promesas.Como vimos al principio de esta unidades lo más importante de las promesas ya que permite evitar la //pirámide de la muerte//.
  
 La forma de conseguir ésto es una nueva funcionalidad del método ''​then''​ de las promesas. Resulta que las 2 primeras funciones de //​callback//​ del método ''​then''​ permiten que se retorne una promesa ((si es un valor en vez de una promesa se transforma en promesa mediante ''​$q.when''​.)) y entonces dicha promesa la retorna el método ''​then''​. ​ La forma de conseguir ésto es una nueva funcionalidad del método ''​then''​ de las promesas. Resulta que las 2 primeras funciones de //​callback//​ del método ''​then''​ permiten que se retorne una promesa ((si es un valor en vez de una promesa se transforma en promesa mediante ''​$q.when''​.)) y entonces dicha promesa la retorna el método ''​then''​. ​
  
-Esto en principio no parece que sea una gran avance pero veamos un ejemplo de como funciona. ​+En principio no parece que ésto sea una gran avance pero veamos un ejemplo de cómo funciona. ​
  
-El ejemplo consiste en gracias ​gracias a la función ''​sumaAsincrona''​ calcular la potencia de (2^4) es decir el valor 16. Para ello llamamos a ''​sumaAsincrona''​ 4 veces sumando a si mismo el valor de la llamada anterior.+El ejemplo consiste en gracias a la función ''​sumaAsincrona''​ calcular la potencia de (2^4) es decir el valor 16. Para ello llamamos a ''​sumaAsincrona''​ 4 veces sumando a sí mismo el valor de la llamada anterior.
  
   * Llamar a ''​sumaAsincrona(1,​1)''​ lo que da un resultado de 2. Usaremos el resultado para la siguiente llamada.   * Llamar a ''​sumaAsincrona(1,​1)''​ lo que da un resultado de 2. Usaremos el resultado para la siguiente llamada.
Línea 244: Línea 244:
 Como vemos cada llamada a ''​sumaAsincrona''​ se hace con el resultado de la llamada anterior, por lo tanto las llamadas están encadenadas. Como vemos cada llamada a ''​sumaAsincrona''​ se hace con el resultado de la llamada anterior, por lo tanto las llamadas están encadenadas.
  
-Si vemos el código siguiente, gracias a las promesas no es necesario tener función de //​callback//​ que dentro tiene otra función de //​callback//​ y así sucesivamente sino que son funciones de //​callback//​ independientes unas de otras. ​Si que están relacionadas pero no es necesario anidarlas.+Si vemos el código siguiente, gracias a las promesas no es necesario tener función de //​callback//​ que dentro tiene otra función de //​callback//​ y así sucesivamente sino que son funciones de //​callback//​ independientes unas de otras. ​Sí están relacionadas pero no es necesario anidarlas.
  
 <sxh js;​highlight:​ [2,​5,​7,​9,​11]>​ <sxh js;​highlight:​ [2,​5,​7,​9,​11]>​
Línea 261: Línea 261:
 </​sxh>​ </​sxh>​
  
-Cada función de //​callback//​ que resuelve la promesa a su vez retorna otra promesa. Ese objeto promesa se retorna en la función ''​then''​ lo que permite ​encadenas ​otras funciones de //​callback//​ y así todas las veces que queramos sin que esté ninguna función de //​callback//​ anidada con ninguna otra.+Cada función de //​callback//​ que resuelve la promesa a su vez retorna otra promesa. Ese objeto promesa se retorna en la función ''​then''​ lo que permite ​encadenar ​otras funciones de //​callback//​ y así todas las veces que queramos sin que esté ninguna función de //​callback//​ anidada con ninguna otra.
  
   * Línea 2: Se genera la primera promesa.   * Línea 2: Se genera la primera promesa.
-  * Línea 5: En esta función de //​callback//​ se coge el resultado que es 2 y se suma a si mismo y se retorna otra promesa. +  * Línea 5: En esta función de //​callback//​ se coge el resultado que es 2 y se suma a sí mismo y se retorna otra promesa. 
-  * Línea 7: En esta función de //​callback//​ se coge el resultado que es 4 y se suma a si mismo y se retorna otra promesa. +  * Línea 7: En esta función de //​callback//​ se coge el resultado que es 4 y se suma a sí mismo y se retorna otra promesa. 
-  * Línea 9: En esta función de //​callback//​ se coge el resultado que es 8 y se suma a si mismo y se retorna otra promesa.+  * Línea 9: En esta función de //​callback//​ se coge el resultado que es 8 y se suma a sí mismo y se retorna otra promesa.
   * Línea 11: Finalmente en la última función de //​callback//​ se muestra el resultado que es de 16.   * Línea 11: Finalmente en la última función de //​callback//​ se muestra el resultado que es de 16.
  
 ==== Recuperarse de un error ==== ==== Recuperarse de un error ====
-Hemos visto como se generan las llamadas si todo funciona correctamente,​ si falla alguna función se detendrá la cadena de llamadas y ya está . Pero hay una forma de poder tratar el error y seguir con la cadena de llamadas. Podemos añadir una función de //​callback//​ para cuando se produce un error y si dicha función de error retorna una promesa ((o un valor que se transformará automáticamente en promesa mediante ''​$q.when''​)) se seguirá la cadena de llamadas como si nada hubiera fallado.+Hemos visto cómo se generan las llamadas si todo funciona correctamente,​ si falla alguna función se detendrá la cadena de llamadas y ya está . Pero hay una forma de poder tratar el error y seguir con la cadena de llamadas. Podemos añadir una función de //​callback//​ para cuando se produce un error y si dicha función de error retorna una promesa ((o un valor que se transformará automáticamente en promesa mediante ''​$q.when''​)) se seguirá la cadena de llamadas como si nada hubiera fallado.
  
 Vamos a modificar nuestro ejemplo para incluir una función en caso de que algo falle en la segunda llamada. Vamos a modificar nuestro ejemplo para incluir una función en caso de que algo falle en la segunda llamada.
Línea 291: Línea 291:
 </​sxh>​ </​sxh>​
   * Línea 8: Se añade la función de //​callback//​ para cuando algo falla.   * Línea 8: Se añade la función de //​callback//​ para cuando algo falla.
-  * Línea 9: Arreglamos el //error// y retornamos el valor que debería ser , que en este caso es un un 4.Al retornar el valor se sigue con las promesas encadenadas como si nada hubiera pasado.+  * Línea 9: Arreglamos el //error// y retornamos el valor que debería ser , que en este caso es un 4.Al retornar el valor se sigue con las promesas encadenadas como si nada hubiera pasado.
  
-El ejemplo es un poco naíf ya que en caso de fallo retornamos directamente el valor correcto, en un caso real seria mas complejo o quizás imposible corregir el fallo y retorna ​otra promesa. Pero aun así sirve para explicar ​como la función de fallo permite seguir con la cadena de promesas.+El ejemplo es un poco naíf ya que en caso de fallo retornamos directamente el valor correcto.  En un caso real sería más complejo o quizás imposible corregir el fallo y retornar ​otra promesa. Pero aún así sirve para explicar ​cómo la función de fallo permite seguir con la cadena de promesas.
  
 ==== Fallo  ==== ==== Fallo  ====
Línea 319: Línea 319:
   * Línea 15: Se ejecutará si alguna de las promesas ha fallado.   * Línea 15: Se ejecutará si alguna de las promesas ha fallado.
  
-<note tip>Por supuesto podría interesarnos saber el paso concreto que ha fallado, en ese caso tendremos que añadir tantas funciones de fallo como promesas haya.</​note>​+<note tip>Por supuesto podría interesarnos saber el paso concreto que ha fallado, en cuyo caso tendremos que añadir tantas funciones de fallo como promesas haya.</​note>​
  
 ==== Progreso ==== ==== Progreso ====
Línea 346: Línea 346:
 </​sxh>​ </​sxh>​
   * Línea 14: Definimos una función de progreso en la última promesa de la cadena de promesas.   * Línea 14: Definimos una función de progreso en la última promesa de la cadena de promesas.
-  * Línea 15: Se ejecutará cada vez que alguna de las promesas notifica algo.En nuestro ejemplo ​la haber 4 llamadas se verá : 0% 33% 66% 100%, 0% 33% 66% 100%, 0% 33% 66% 100%, 0% 33% 66% 100%. +  * Línea 15: Se ejecutará cada vez que alguna de las promesas notifica algo.En nuestro ejemplo ​al haber 4 llamadas se verá : 0% 33% 66% 100%, 0% 33% 66% 100%, 0% 33% 66% 100%, 0% 33% 66% 100%. 
  
-<note tip>Por supuesto podría interesarnos saber por separado las notificaciones de cada promesa, en ese caso tendremos que añadir tantas funciones de notificación como promesas haya.</​note>​+<note tip>Por supuesto podría interesarnos saber por separado las notificaciones de cada promesa,en ese caso tendremos que añadir tantas funciones de notificación como promesas haya.</​note>​
  
  
 ===== Ejemplo ===== ===== Ejemplo =====
-El ejemplo contiene llamadas a todas los los métodos que hemos visto en este tema por lo que el código JavaScript ha quedado un poco largo, y se ven lo siguiente:+El ejemplo contiene llamadas a todas los métodos que hemos visto en este tema por lo que el código JavaScript ha quedado un poco largo, y se ve lo siguiente:
   * Notificaciones   * Notificaciones
   * Función de finalización   * Función de finalización
unidades/06_promesas/03_avanzado.txt · Última modificación: 2014/09/02 00:16 por admin
Ir hasta arriba
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0