javascript - then - ¿Por qué las devoluciones de llamadas están más "estrechamente unidas" que las promesas?
promise all (5)
¿Puede explicarme la siguiente frase (tomada de una respuesta a la pregunta de Stack Overflow ¿ Cuáles son las diferencias entre Deferred, Promise y Future en Javascript? )?
¿Cuáles son las ventajas de utilizar las promesas de jQuery contra el uso de las devoluciones de llamada jQuery anteriores?
En lugar de pasar retrollamadas directamente a las funciones, algo que puede conducir a interfaces estrechamente conectadas, el uso de promesas permite separar preocupaciones para el código que es síncrono o asíncrono.
El acoplamiento es más flexible con promesas porque la operación no tiene que "saber" cómo continúa, solo tiene que saber cuándo está lista.
Cuando utiliza devoluciones de llamada, la operación asíncrona en realidad tiene una referencia a su continuación, que no es asunto suyo.
Con las promesas, puede crear fácilmente una expresión sobre una operación asíncrona incluso antes de decidir cómo se resolverá.
Entonces las promesas ayudan a separar las preocupaciones de encadenar eventos versus hacer el trabajo real.
Las promesas reifican el concepto de respuesta retrasada a algo. Hacen que el cálculo asincrónico sea un ciudadano de primera clase, ya que puedes pasarlo por alto. Le permiten definir la estructura si lo desea, es decir, una estructura monádica, sobre la cual puede construir combinators de orden superior que simplifiquen enormemente el código.
Por ejemplo, puede tener una función que toma una serie de promesas y devuelve la promesa de una matriz (por lo general, esto se denomina sequence
). Esto es muy difícil de hacer o incluso imposible con devoluciones de llamadas. Y estos combinadores no solo hacen que el código sea más fácil de escribir, sino que lo hacen mucho más fácil de leer.
Ahora considere lo contrario para responder su pregunta. Las rellamadas son una solución ad-hoc donde las promesas permiten una estructura más clara y una reutilización.
No creo que las promesas estén más o menos acopladas que las devoluciones de llamadas, casi lo mismo.
Las promesas, sin embargo, tienen otros beneficios:
Si expone una devolución de llamada, debe documentar si se llamará una vez (como en jQuery.ajax) o más de una vez (como en Array.map). Las promesas se llaman siempre una vez.
No hay forma de invocar una devolución de llamada y una excepción, por lo que debe proporcionar otra devolución de llamada para el caso de error.
Solo se puede registrar una devolución de llamada, más de una para las promesas, y puede registrarlas DESPUÉS del evento y se le llamará de todos modos.
En una declaración tipeada (Typescript), Promise hace más fácil leer la firma.
En el futuro, puede aprovechar una sintaxis asíncrona / rendimiento.
Debido a que son estándar, puede hacer componentes reutilizables como este:
disableScreen<T>(promiseGenerator: () => Promise<T>) : Promise<T> { //create transparent div return promiseGenerator.then(val=> { //remove transparent div return val; }, error=>{ //remove transparent div throw error; }); } disableScreen(()=>$.ajax(....));
Más sobre eso: html5rocks.com/en/tutorials/es6/promises
EDITAR:
- Otro beneficio es escribir una secuencia de N llamadas sincronizadas sin N niveles de sangría.
Además, aunque todavía no creo que sea el punto principal, ahora creo que están un poco más flojos por estas razones:
Son estándar (o al menos lo intentan): el código en C # o Java que usa cadenas están más mal acoplados que el código similar en C ++, debido a las diferentes implementaciones de cadenas allí, lo que lo hace más reutilizable. Al tener una promesa estándar, la persona que llama y la implementación están menos acopladas entre sí porque no tienen que ponerse de acuerdo sobre un (par) de devoluciones de llamadas personalizadas con parámetros personalizados, pedidos, nombres, etc. El hecho de que hay muchos diferentes sabores en las promesas no ayuda el pensamiento.
Promueven una programación más basada en la expresión, más fácil de componer, caché, etc.
var cache: { [key: string] : Promise<any> }; function getData(key: string): Promise<any> { return cache[key] || (cache[key] = getFromServer(key)); }
se puede argumentar que la programación basada en expresiones está más vagamente acoplada que la programación basada en llamadas / imperativos, o al menos persiguen el mismo objetivo: la capacidad de compilación.
No lo son, esto es solo una racionalización que las personas que están perdiendo por completo el punto de las promesas utilizan para justificar escribir mucho más código de lo que escribirían usando devoluciones de llamada. Dado que obviamente no hay ningún beneficio al hacer esto, al menos siempre puede decirse a sí mismo que el código está menos acoplado o algo así.
Vea cuáles son las promesas y por qué debería usarlas para obtener beneficios concretos reales.
Una promesa es un objeto que representa el resultado de una operación asincrónica , y debido a eso puede pasarlo por alto, y eso le da más flexibilidad.
Si utiliza una devolución de llamada, en el momento de la invocación de la operación asíncrona debe especificar cómo se manejará, de ahí el acoplamiento. Con promesas puedes especificar cómo se manejará más tarde.
Aquí hay un ejemplo, imagine que desea cargar algunos datos mediante ajax y mientras lo hace, desea mostrar una página de carga.
Con devoluciones de llamada:
void loadData = function(){
showLoadingScreen();
$.ajax("http://someurl.com", {
complete: function(data){
hideLoadingScreen();
//do something with the data
}
});
};
La devolución de llamada que maneja los datos que regresan tiene que llamar a hideLoadingScreen.
Con las promesas, puede volver a escribir el fragmento anterior para que sea más legible y no tenga que colocar hideLoadingScreen en la devolución de llamada completa.
Con promesas
var getData = function(){
showLoadingScreen();
return $.ajax("http://someurl.com").promise().always(hideLoadingScreen);
};
var loadData = function(){
var gettingData = getData();
gettingData.done(doSomethingWithTheData);
}
var doSomethingWithTheData = function(data){
//do something with data
};
ACTUALIZACIÓN: He escrito una publicación de blog que proporciona ejemplos adicionales y proporciona una descripción clara de lo que es una promesa y cómo se puede comparar su uso con el uso de devoluciones de llamada.