Sowohl Futures als auch Versprechen blockieren, bis sie ihre Werte berechnet haben. Was ist also der Unterschied zwischen ihnen?
Sowohl Futures als auch Versprechen blockieren, bis sie ihre Werte berechnet haben. Was ist also der Unterschied zwischen ihnen?
Antworten:
In Clojure-Begriffen antworten, hier einige Beispiele aus Sean Devlins Screencast :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Beachten Sie, dass Sie im Versprechen explizit einen Wert liefern, den Sie in einer späteren Berechnung ( :fredin diesem Fall) auswählen . Die Zukunft hingegen wird an dem Ort konsumiert, an dem sie geschaffen wurde. Das some-exprwird vermutlich hinter den Kulissen gestartet und (eventuell) im Tandem berechnet. Wenn es jedoch zum Zeitpunkt des Zugriffs nicht bewertet wird, werden die Thread-Blöcke bis zur Verfügbarkeit angezeigt.
bearbeitet, um hinzuzufügen
Beachten Sie Folgendes, um die Unterscheidung zwischen einem Versprechen und einer Zukunft zu erleichtern:
promise. Dieses Versprechungsobjekt kann jetzt an einen beliebigen Thread übergeben werden.deliverdie Ergebnisse für dieses Versprechenobjekt anzeigen.derefIhr Versprechen zu erfüllen, bevor Sie mit Ihrer Berechnung fertig sind, wird blockiert, bis Sie fertig sind. Sobald Sie fertig sind und deliverdas Versprechen eingelöst haben, wird das Versprechen nicht mehr blockiert.derefdie Zukunft. Wenn die Berechnung bereits abgeschlossen ist, erhalten Sie die Ergebnisse. Wenn es noch nicht abgeschlossen ist, blockieren Sie, bis es abgeschlossen ist. (Wenn es vermutlich noch nicht gestartet wurde, derefbedeutet dies, dass es ausgeführt wird, aber auch dies ist nicht garantiert.)Während Sie den Ausdruck in Zukunft so kompliziert machen könnten wie den Code, der auf die Erstellung eines Versprechens folgt, ist es zweifelhaft, dass dies wünschenswert ist. Dies bedeutet, dass Futures eher für schnelle, hintergrundfähige Berechnungen geeignet sind, während Versprechen eher für große, komplizierte Ausführungspfade geeignet sind. Außerdem scheinen Versprechen in Bezug auf die verfügbaren Berechnungen etwas flexibler und auf den Versprechensschöpfer ausgerichtet zu sein, der die Arbeit erledigt, und auf einen anderen Faden, der die Ernte erntet. Futures sind eher darauf ausgerichtet, einen Thread automatisch zu starten (ohne den hässlichen und fehleranfälligen Overhead) und mit anderen Dingen fortzufahren, bis Sie - der ursprüngliche Thread - die Ergebnisse benötigen.
futureVeranschaulichung , der Hauptteil eines Anrufs kann N sexprs enthalten.
Sowohl Future als auch Promise sind Mechanismen zur Kommunikation des Ergebnisses asynchroner Berechnungen vom Produzenten an den Verbraucher.
Im Falle von Future wird die Berechnung zum Zeitpunkt der Future-Erstellung definiert und die asynchrone Ausführung beginnt "ASAP". Es "weiß" auch, wie eine asynchrone Berechnung erzeugt wird.
Im Falle des Versprechens werden die Berechnung , die Startzeit und der [mögliche] asynchrone Aufruf vom Übermittlungsmechanismus entkoppelt. Wenn das Berechnungsergebnis verfügbar ist, muss der Produzent deliverexplizit aufrufen. Dies bedeutet auch, dass der Produzent steuert, wann das Ergebnis verfügbar wird.
Für Versprechen macht Clojure einen Entwurfsfehler, indem er dasselbe Objekt (Ergebnis des promiseAufrufs) verwendet, um das Ergebnis der Berechnung zu erzeugen ( deliver) und zu verbrauchen ( deref) . Dies sind zwei sehr unterschiedliche Fähigkeiten, die als solche behandelt werden sollten.
promisees bequem wäre, die Sicherheit an einen so einfachen Referenztyp zu koppeln (siehe Impl) . "Böse" Verbraucher sind selten; Nichts hindert Sie daran, Ihre eigene Abstraktion auf Versprechungen aufzubauen.
(defn undeliverable-promise [] (let [p (promise)] (reify clojure.lang.IDeref (deref [_] (deref p)) clojure.lang.IBlockingDeref (deref [_ ms val] (deref p ms val)) clojure.lang.IPending (isRealized [_] (.isRealized p)) clojure.lang.IFn (invoke [_ _] nil))))
Es gibt bereits hervorragende Antworten, daher wird nur die Zusammenfassung "Verwendung" hinzugefügt:
Beide
Wenn Sie ein Versprechen oder eine Zukunft erstellen, wird sofort eine Referenz zurückgegeben. Diese Referenz blockiert @ / deref, bis das Ergebnis der Berechnung von einem anderen Thread bereitgestellt wird.
Zukunft
Beim Erstellen einer Zukunft stellen Sie einen synchronen Job bereit, der ausgeführt werden muss. Es wird in einem Thread aus dem dedizierten unbegrenzten Pool ausgeführt.
Versprechen
Sie geben keine Argumente an, wenn Sie ein Versprechen erstellen. Die Referenz sollte an einen anderen 'Benutzer'-Thread übergeben werden, der deliverdas Ergebnis liefert.
In Clojure, promise, future, und delaysind Versprechen ähnliche Objekte. Sie alle stellen eine Berechnung dar, auf die Clients mit deref(oder @) warten können . Clients verwenden das Ergebnis erneut, sodass die Berechnung nicht mehrmals ausgeführt wird.
Sie unterscheiden sich in der Art und Weise, wie die Berechnung durchgeführt wird:
futurestartet die Berechnung in einem anderen Worker-Thread. derefwird blockiert, bis das Ergebnis fertig ist.
delayführt die Berechnung träge durch, wenn der erste Client verwendet deref, oder force.
promisebietet die größte Flexibilität, da das Ergebnis durch Verwendung auf jede benutzerdefinierte Weise geliefert wird deliver. Sie verwenden es, wenn keines futureoder delayIhr Anwendungsfall übereinstimmt.
Erstens ist a Promisea Future. Ich denke, Sie möchten den Unterschied zwischen a Promiseund a kennen FutureTask.
A Futurestellt einen Wert dar, der derzeit nicht bekannt ist, aber in Zukunft bekannt sein wird.
A FutureTaskstellt das Ergebnis einer Berechnung dar, die in Zukunft stattfinden wird (möglicherweise in einem Thread-Pool). Wenn Sie versuchen, auf das Ergebnis zuzugreifen, wird die Berechnung blockiert, wenn sie noch nicht erfolgt ist. Andernfalls wird das Ergebnis sofort zurückgegeben. Es ist keine andere Partei an der Berechnung des Ergebnisses beteiligt, da die Berechnung von Ihnen im Voraus festgelegt wurde.
A Promisestellt ein Ergebnis dar, das der Versprechende dem Versprechenden in Zukunft liefern wird. In diesem Fall sind Sie der Versprechende und der Versprechende ist derjenige, der Ihnen das PromiseObjekt gegeben hat. Ähnlich wie bei FutureTask, wenn Sie versuchen, auf das Ergebnis zuzugreifen, bevor das Promiseerfüllt wurde, wird es blockiert, bis der Promiser das erfüllt Promise. Sobald das Promiseerfüllt ist, erhalten Sie immer und sofort den gleichen Wert. Im Gegensatz zu a FutureTaskist hier eine andere Partei beteiligt, die die Promise. Dass eine andere Partei für die Berechnung und Erfüllung der Promise.
In diesem Sinne ist a FutureTaskein, das Promisedu dir selbst gemacht hast.