Wie kann Clojure Futures und Versprechungen unterscheiden?
-
30-09-2019 - |
Frage
Beide Futures und Versprechungen blockieren, bis sie ihre Werte berechnet haben, so was ist der Unterschied zwischen ihnen?
Lösung
Die Beantwortung in Clojure Begriffe, hier sind einige Beispiele von Sean Devlin Screencasts :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
Beachten Sie, dass Sie in der Verheißung werden explizit einen Wert zu liefern, dass Sie in einer späteren Berechnung wählen (:fred
in diesem Fall). Die Zukunft, auf der anderen Seite, wird an der gleichen Stelle verbraucht, dass sie erstellt wurde. Die some-expr
wird vermutlich hinter den Kulissen ins Leben gerufen und im Tandem (schließlich) berechnet, aber wenn es um die Zeit nicht ausgewertete bleibt es die Gewindeblocks zugegriffen, bis es verfügbar ist.
bearbeitet hinzufügen
Um die Hilfe weiter unterscheiden zwischen dem Versprechen und Zukunft muss folgendes beachtet werden:
versprechen
- Sie erstellen eine
promise
. Dieses Versprechen Objekt kann jetzt zu jedem Thread übergeben werden. - Sie auch weiterhin mit Berechnungen. Diese können sehr komplizierte Berechnungen, die Nebenwirkungen, das Herunterladen von Daten, Benutzereingabe, Datenbankzugriff, andere Versprechungen - was auch immer Sie mögen. Der Code wird sehr viel aussehen wie Ihre Hauptstrecke Code in einem beliebigen Programm.
- Wenn Sie fertig sind, können Sie die Ergebnisse dieses Versprechen Objekt
deliver
. - Jedes Element, das versucht, Ihr Versprechen
deref
, bevor Sie mit Ihrer Berechnung fertig sind blockiert, bis Sie fertig sind. Sobald Sie fertig sind, und Sie haben das Versprechendeliver
ed, wird das Versprechen nicht mehr blockieren.
Zukunft
- Sie erstellen Ihre Zukunft. Ein Teil Ihrer Zukunft ist ein Ausdruck für die Berechnung.
- Die Zukunft kann oder auch nicht gleichzeitig ausgeführt werden. Es könnte einen Thread zugewiesen werden, möglicherweise aus einem Pool. Es könnte nur warten und nichts tun. Aus Ihrer Sicht Sie können nicht sagen, .
- An einem gewissen Punkt, den Sie (oder ein anderer Thread)
deref
s die Zukunft. Wenn die Berechnung bereits abgeschlossen hat, erhalten Sie die Ergebnisse davon. Wenn es nicht bereits abgeschlossen hat, blockieren Sie, bis es hat. (Vermutlich, wenn sie noch nicht begonnen hat,deref
ing es bedeutet, dass es auszuführen beginnt, aber auch dies ist nicht garantiert.)
Während Sie konnte , um den Ausdruck in der Zukunft so groß wie der Code kompliziert, dass die Schaffung eines Versprechens folgt, ist es zweifelhaft, dass wünschenswert ist. Dies bedeutet, dass Futures ist wirklich mehr geeignet, um schnell, Hintergrund-able Berechnungen während Versprechen wirklich mehr geeignet, um große, komplizierte Ausführungspfade. Auch Versprechen scheinen, in Bezug auf die Berechnungen, ein wenig flexibler und orientiert sich das Versprechen Schöpfer die Arbeit und ein anderer Thread tun die Ernte ernten. Futures sind mehr orientiert sich automatisch einen Thread starten (ohne die hässlichen und fehleranfällig Overhead) und geht mit anderen Dingen, bis Sie - den Ursprung Thread -. Bedarf die Ergebnisse
Andere Tipps
Sowohl Zukunft und Versprechen sind Mechanismen Ergebnis der asynchrone Kommunikation Berechnung vom Erzeuger zum Verbraucher (s).
Im Fall von Future die Berechnung wird zum Zeitpunkt der zukünftigen Gestaltung und asynchrone Ausführung beginnt definiert „so schnell wie möglich“. Es „weiß“, wie auch eine asynchrone Berechnung, um laichen.
Im Fall von Versprechen die Berechnung , sein Startzeit und [möglich] asynchronen Aufruf ist von dem Abgabemechanismus entkoppelt . Wenn Berechnung Ergebnis verfügbar Producer ist ausdrücklich deliver
nennen muss, was auch bedeutet, dass die Erzeuger Kontrollen , wenn Ergebnis verfügbar wird.
Für Promises macht Clojure ein Design Fehler durch das gleiche Objekt (Ergebnis der promise
Anruf) unter Verwendung sowohl Produkte (deliver
) und verbrauchen (deref
) das Ergebnis von Berechnung . Dies sind zwei sehr unterschiedliche Fähigkeiten und sollten als solche behandelt werden.
Es gibt bereits sehr gute Antworten, so dass nur das Hinzufügen der Zusammenfassung "how to use":
Sowohl
Erstellen von Versprechen oder zukünftige Erträge sofort eine Referenz. Diese Referenzblocks auf @ / deref bis Ergebnis der Berechnung wird von anderem Thread zur Verfügung gestellt.
Future
Wenn Zukunft zu schaffen bieten Sie eine synchrone Arbeit geleistet werden. Es ist in einem Thread aus dem dedizierten Pool unbeschränkt ausgeführt.
Versprechen
Sie geben keine Argumente, wenn Versprechen zu schaffen. Das sollte auf anderen ‚Benutzer‘ Thread übergeben werden, die das Ergebnis deliver
wird.
Zum einen ist ein Promise
ein Future
. Ich denke, dass Sie den Unterschied zwischen einem Promise
und einem FutureTask
wissen will.
Ein Future
stellt einen Wert dar, der derzeit nicht bekannt ist, aber in der Zukunft bekannt sein.
Ein FutureTask
stellt das Ergebnis einer Berechnung, die in Zukunft (vielleicht in einem Thread-Pool) passieren wird. Wenn Sie versuchen, das Ergebnis zu gelangen, wenn die Berechnung noch nicht geschehen ist, blockiert es. Andernfalls wird das Ergebnis sofort zurückgegeben. Es gibt kein anderes in der Berechnung der Folge beteiligte Partei wie die Berechnung von Ihnen im Voraus festgelegt ist.
Ein Promise
repräsentiert ein Ergebnis, das durch die Promiser zum promisee in Zukunft überbracht. In diesem Fall sind Sie das Versprechen und die Promiser sind, dass derjenige, den Ihnen das Objekt Promise
gab. Ähnlich wie bei der FutureTask
, wenn Sie versuchen, das Ergebnis zu gelangen, bevor die Promise
erfüllt ist, wird es blockiert, bis der Promiser die Promise
erfüllt. Sobald die Promise
erfüllt ist, erhalten Sie den gleichen Wert immer und sofort. Im Gegensatz zu einem FutureTask
gibt es eine andere Partei hier beteiligt ist, eine, die die Promise
gemacht. Dass eine andere Partei, die Berechnung zu tun und die Erfüllung der Promise
verantwortlich ist.
In diesem Sinne ein FutureTask
ist ein Promise
Sie sich selbst gemacht.