Saltar al contenido

¿Cuál es la diferencia entre un futuro y una promesa?

Solución:

(No estoy completamente satisfecho con las respuestas hasta ahora, así que aquí está mi intento …)

Creo que el comentario de Kevin Wright (“Puedes hacer una promesa y depende de ti mantenerla. Cuando alguien más te hace una promesa, debes esperar para ver si la cumplen en el futuro”.) lo resume bastante bien, pero alguna explicación puede ser útil.

Los futuros y las promesas son conceptos bastante similares, la diferencia es que un futuro es un contenedor de solo lectura para un resultado que aún no existe, mientras que una promesa se puede escribir (normalmente solo una vez). Java 8 CompletableFuture y Guava SettableFuture pueden considerarse promesas, porque su valor se puede establecer (“completar”), pero también implementan la interfaz Future, por lo que no hay diferencia para el cliente.

El resultado del futuro será establecido por “otra persona”, por el resultado de un cálculo asincrónico. Note cómo FutureTask – un futuro clásico – debe inicializarse con un Callable o Runnable, no hay un constructor sin argumentos, y tanto Future como FutureTask son de solo lectura desde el exterior (los métodos establecidos de FutureTask están protegidos). El valor se establecerá en el resultado del cálculo desde el interior.

Por otro lado, “usted” (o de hecho, cualquier persona) puede establecer el resultado de una promesa en cualquier momento porque tiene un método de establecimiento público. Tanto CompletableFuture como SettableFuture se pueden crear sin ninguna tarea y su valor se puede establecer en cualquier momento. Envías una promesa al código de cliente y la cumples más tarde como desees.

Tenga en cuenta que CompletableFuture no es una promesa “pura”, se puede inicializar con una tarea como FutureTask, y su característica más útil es el encadenamiento no relacionado de pasos de procesamiento.

También tenga en cuenta que una promesa no tiene que ser un subtipo de futuro y no tiene que ser el mismo objeto. En Scala, un objeto Future se crea mediante un cálculo asincrónico o mediante un diferente Objeto de promesa. En C ++ la situación es similar: el objeto de promesa es utilizado por el productor y el objeto futuro por el consumidor. La ventaja de esta separación es que el cliente no puede establecer el valor del futuro.

Tanto Spring como EJB 3.1 tienen una clase AsyncResult, que es similar a las promesas de Scala / C ++. AsyncResult implementa Future pero este no es el futuro real: los métodos asincrónicos en Spring / EJB devuelven un objeto Future diferente de solo lectura a través de magia de fondo, y este segundo futuro “real” puede ser utilizado por el cliente para acceder al resultado.

Según esta discusión, Promise finalmente ha sido llamado CompletableFuture para su inclusión en Java 8, y su javadoc explica:

Un Futuro que puede completarse explícitamente (estableciendo su valor y estado), y puede usarse como CompletionStage, apoyando funciones dependientes y acciones que se activan una vez finalizado.

También se da un ejemplo en la lista:

f.then((s -> aStringFunction(s)).thenAsync(s -> ...);

Tenga en cuenta que la API final es ligeramente diferente pero permite una ejecución asincrónica similar:

CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);

Soy consciente de que ya hay una respuesta aceptada, pero me gustaría agregar mis dos centavos de todos modos:

TLDR: Future y Promise son los dos lados de una operación asincrónica: consumidor / llamador vs. productor / implementador.

Como un llamador de un método API asincrónico, obtendrá un Future como un identificador del resultado del cálculo. Puede, por ejemplo, llamar get() en él para esperar a que se complete el cálculo y recuperar el resultado.

Ahora piense en cómo se implementa realmente este método de API: implementador debe devolver un Future inmediatamente. Son responsables de completar ese futuro tan pronto como se realice el cálculo (lo sabrán porque está implementando la lógica de despacho ;-)). Usarán un Promise/CompletableFuture para hacer precisamente eso: Construya y devuelva el CompletableFuture inmediatamente, y llame complete(T result) una vez que se realiza el cálculo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *