Les contrats à terme et les promesses se bloquent jusqu'à ce qu'ils aient calculé leurs valeurs, alors quelle est la différence entre eux?
Répondant en termes de Clojure, voici quelques exemples de screencast de Sean Devlin :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Notez que dans la promesse, vous fournissez explicitement une valeur que vous sélectionnez dans un calcul ultérieur (:fred
dans ce cas). L'avenir, en revanche, se consomme au même endroit qu'il a été créé. Le some-expr
est vraisemblablement lancé en arrière-plan et calculé en tandem (éventuellement), mais s'il reste non évalué au moment où il est accédé aux blocs de threads jusqu'à ce qu'il soit disponible.
modifié pour ajouter
Pour aider à mieux distinguer entre une promesse et un avenir, notez ce qui suit:
promise
. Cet objet de promesse peut désormais être transmis à n'importe quel thread.deliver
les résultats de cet objet de promesse.deref
votre promesse avant que vous ayez terminé votre calcul sera bloqué jusqu'à ce que vous ayez terminé. Une fois que vous avez terminé et que vous avez deliver
ed la promesse, la promesse ne bloquera plus.deref
s le futur. Si le calcul est déjà terminé, vous en obtenez les résultats. Si ce n'est pas déjà fait, vous bloquez jusqu'à ce qu'il l'ait. (Vraisemblablement, s'il n'a pas encore commencé, deref
ing signifie qu'il commence à s'exécuter, mais cela aussi n'est pas garanti.)Alors que vous pourriez rendre l'expression à l'avenir aussi compliquée que le code qui suit la création d'une promesse, il est peu probable que ce soit souhaitable. Cela signifie que les contrats à terme sont vraiment plus adaptés aux calculs rapides et en arrière-plan, tandis que les promesses sont vraiment plus adaptées aux grands chemins d'exécution compliqués. Trop, les promesses semblent, en termes de calculs disponibles, un peu plus flexibles et orientées vers le créateur de la promesse qui fait le travail et un autre fil récoltant la récolte. Les futurs sont plus orientés vers le démarrage automatique d'un thread (sans la surcharge laide et sujette aux erreurs) et la poursuite d'autres choses jusqu'à ce que vous - le thread d'origine - ayez besoin des résultats.
Future et Promise sont des mécanismes pour communiquer le résultat du calcul asynchrone du producteur au (x) consommateur (s).
Dans le cas de Future le calcul est défini au moment de la création Future et l'exécution asynchrone commence "ASAP ". Il "sait" également comment générer un calcul asynchrone.
Dans le cas de Promise le calcul , son heure de début et [possible] l'appel asynchrone sont découplés du mécanisme de livraison. Lorsque le résultat du calcul est disponible, le producteur doit appeler deliver
explicitement, ce qui signifie également que le producteur contrôle lorsque le résultat devient disponible.
Pour Promesses Clojure fait une erreur de conception en utilisant le même objet (résultat de l'appel de promise
) pour produire (deliver
) et consommer (deref
) le résultat du calcul . Ce sont deux capacités très distinctes et doivent être traitées comme telles.
Il y a déjà d'excellentes réponses, donc ajoutez seulement le résumé "comment utiliser":
Les deux
La création d'une promesse ou d'un futur renvoie immédiatement une référence. Cette référence se bloque sur @/deref jusqu'à ce que le résultat du calcul soit fourni par un autre thread.
Futur
Lors de la création du futur, vous fournissez un travail synchrone à effectuer. Il est exécuté dans un thread du pool illimité dédié.
Promesse
Vous ne donnez aucun argument lors de la création de la promesse. La référence doit être passée à un autre thread 'utilisateur' qui deliver
le résultat.