webentwicklung-frage-antwort-db.com.de

Was sind die Unterschiede zwischen Deferred, Promise und Future in JavaScript?

Was sind die Unterschiede zwischen Aufgeschoben, Versprechen und Futures?
Gibt es eine allgemein anerkannte Theorie hinter all diesen drei?

296
Tower

In Anbetracht der offensichtlichen Abneigung dagegen, wie ich versucht habe, die Frage des OP zu beantworten. Die wörtliche Antwort lautet: Ein Versprechen ist etwas, das mit anderen Objekten geteilt wird, während ein aufgeschobenes Versprechen geheim gehalten werden sollte. In erster Linie kann sich ein zurückgestellter (der im Allgemeinen das Versprechen erweitert) selbst auflösen, während ein Versprechen dies möglicherweise nicht kann.

Wenn Sie an den Minutien interessiert sind, prüfen Sie Versprechen/A + .


Der übergeordnete Zweck besteht meines Wissens darin, die Übersichtlichkeit zu verbessern und die Kopplung über eine standardisierte Schnittstelle zu lockern. Siehe Lesevorschlag von @ jfriend00:

Anstatt Rückrufe direkt an Funktionen weiterzuleiten, was zu eng gekoppelten Schnittstellen führen kann, können Sie mithilfe von Versprechungen Bedenken für synchronen oder asynchronen Code trennen.

Persönlich habe ich aufgeschoben besonders nützlich gefunden, wenn es z. Vorlagen, die mit asynchronen Anforderungen gefüllt sind, Skripten mit Abhängigkeiten laden und Benutzerfeedback bereitstellen, um Daten blockierungsfrei zu bilden.

Vergleichen Sie in der Tat die reine Callback-Form, nach dem asynchronen Laden von CodeMirror im JS-Modus etwas zu tun (Entschuldigung, ich habe jQuery nicht in einem while verwendet):

/* assume getScript has signature like: function (path, callback, context) 
   and listens to onload && onreadystatechange */
$(function () {
   getScript('path/to/CodeMirror', getJSMode);

   // onreadystate is not reliable for callback args.
   function getJSMode() {
       getScript('path/to/CodeMirror/mode/javascript/javascript.js', 
           ourAwesomeScript);
   };

   function ourAwesomeScript() {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   };
});

Zu der versprochenen formulierten Version (wieder entschuldige, ich bin nicht auf dem neuesten Stand bei jQuery):

/* Assume getScript returns a promise object */
$(function () {
   $.when(
       getScript('path/to/CodeMirror'),
       getScript('path/to/CodeMirror/mode/javascript/javascript.js')
   ).then(function () {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   });
});

Entschuldigung für den Semi-Pseudo-Code, aber ich hoffe, es macht die Kernidee etwas klarer. Grundsätzlich können Sie durch die Rückgabe eines standardisierten Versprechens das Versprechen weitergeben und so eine klarere Gruppierung ermöglichen.

96
fncomp

Diese Antworten, einschließlich der ausgewählten Antwort, eignen sich gut für die konzeptionelle Einführung von Versprechungen, es fehlen jedoch Einzelheiten zu den Unterschieden in der Terminologie, die sich bei der Verwendung von Bibliotheken ergeben, die sie implementieren (und es gibt wichtige Unterschiede).

Da es sich immer noch um eine sich entwickelnde Spezifikation handelt, stammt die Antwort derzeit aus dem Versuch, sowohl Referenzen (wie wikipedia ) als auch Implementierungen (wie jQuery ) zu untersuchen:

  • Aufgeschoben : Nie in populären Referenzen beschrieben, 124 Wird jedoch häufig von Implementierungen als Schiedsrichter für die Lösung von Versprechungen verwendet (Implementierung von resolve und reject). 567

    Manchmal sind Aufschübe auch Versprechungen (Implementierung von then), 56 In anderen Fällen wird es als reiner angesehen, wenn die Option "Zurückgestellt" nur zur Auflösung in der Lage ist und der Benutzer gezwungen wird, auf das Versprechen für die Verwendung von then zuzugreifen. 7

  • Versprechen : Das umfassendste Wort für die in Rede stehende Strategie.

    Ein Proxy-Objekt, das das Ergebnis einer Zielfunktion speichert, deren Synchronität wir abstrahieren möchten. Außerdem wird eine then -Funktion verfügbar gemacht, die eine andere Zielfunktion akzeptiert und ein neues Versprechen zurückgibt. 2

    Beispiel aus CommonJS :

    > asyncComputeTheAnswerToEverything()
        .then(addTwo)
        .then(printResult);
    44
    

    Immer beschrieben in populären Referenzen, obwohl nie spezifiziert, wessen Verantwortlichkeitsentscheidung unterliegt. 124

    In gängigen Implementierungen immer präsent und nie mit Lösungsmöglichkeiten ausgestattet. 567

  • Future : Ein scheinbar veralteter Begriff, der in einigen populären Literaturstellen vorkommt 1 und mindestens eine beliebte Implementierung, 8 aber anscheinend aus der Diskussion gestrichen, weil der Begriff "Versprechen" vorgezogen wird  und nicht immer in populären Einführungen zum Thema erwähnt. 9

    Mindestens eine Bibliothek verwendet den Begriff jedoch generisch, um Synchronität und Fehlerbehandlung zu abstrahieren, ohne die Funktionalität von then bereitzustellen. 1 Es ist unklar, ob das Vermeiden des Begriffs "Versprechen" beabsichtigt war, aber wahrscheinlich eine gute Wahl, da Versprechen auf "thenables" basieren. 2

Verweise

  1. Wikipedia auf Promises & Futures
  2. Versprechen/A + spec
  3. DOM-Standard bei Versprechungen
  4. DOM-Standard verspricht Spec WIP
  5. DOJO Toolkit wird zurückgestellt
  6. jQuery Deferred
  7. Q
  8. FutureJS
  9. Funktionaler Javascript-Abschnitt über Versprechen
  10. Futures im AngularJS Integrationstest

Verschiedene möglicherweise verwirrende Dinge

143
Woahdae

Was mich wirklich zum Klicken brachte, war diese Präsentation von Domenic Denicola.

In einem Github Gist gab er die Beschreibung, die ich am meisten mag, es ist sehr prägnant:

Der Sinn des Versprechens ist es, uns in der asynchronen Welt die funktionale Zusammensetzung und das Auftreten von Fehlern zurückzugeben.

Mit anderen Worten, Versprechen sind eine Methode, mit der wir asynchron Code schreiben können, der fast so einfach zu schreiben ist, als wäre er synchron.

Betrachten Sie dieses Beispiel mit Versprechungen:

getTweetsFor("domenic") // promise-returning async function
    .then(function (tweets) {
        var shortUrls = parseTweetsForUrls(tweets);
        var mostRecentShortUrl = shortUrls[0];
        return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
    })
    .then(doHttpRequest) // promise-returning async function
    .then(
        function (responseBody) {
            console.log("Most recent link text:", responseBody);
        },
        function (error) {
            console.error("Error with the twitterverse:", error);
        }
    );

Es funktioniert so, als ob Sie diesen synchronen Code schreiben würden:

try {
    var tweets = getTweetsFor("domenic"); // blocking
    var shortUrls = parseTweetsForUrls(tweets);
    var mostRecentShortUrl = shortUrls[0];
    var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
    console.log("Most recent link text:", responseBody);
} catch (error) {
    console.error("Error with the twitterverse: ", error);
}

(Wenn dies immer noch kompliziert klingt, sehen Sie sich diese Präsentation an!)

In Bezug auf Aufgeschoben ist dies ein Weg, um .resolve() oder .reject() zu versprechen. In der Promises/B Spezifikation heißt es .defer(). In jQuery ist es $.Deferred().

Bitte beachten Sie, dass meines Wissens die Promise-Implementierung in jQuery fehlerhaft ist (siehe Gist), zumindest ab jQuery 1.8.2.
Es implementiert angeblich Promises/A thenables , aber Sie erhalten nicht die richtige Fehlerbehandlung, die Sie sollten, in dem Sinne, dass die gesamte asynchrone Try/Catch-Funktionalität nicht funktioniert . Schade, denn ein "try/catch" mit asynchronem Code ist absolut cool.

Wenn Sie Promises verwenden möchten (Sie sollten sie mit Ihrem eigenen Code ausprobieren!), Verwenden Sie Kris Kowals Q . Die jQuery-Version ist nur ein Callback-Aggregator zum Schreiben von saubererem jQuery-Code.

In Bezug auf Future habe ich keine Ahnung, das habe ich in keiner API gesehen.

Bearbeiten: Domenic Denicolas YouTube-Vortrag über Versprechen von @ Farm s Kommentar unten.

Ein Zitat von Michael Jackson (ja, Michael Jackson) aus dem Video:

Ich möchte, dass Sie diesen Satz in Erinnerung behalten: Ein Versprechen ist ein asynchroner Wert .

Dies ist eine hervorragende Beschreibung: Ein Versprechen ist wie eine Variable aus der Zukunft - ein erstklassiger Verweis auf etwas, das irgendwann existieren wird (oder passieren wird).

72
Camilo Martin

Ein Promise repräsentiert einen Proxy für einen Wert, der nicht unbedingt bekannt ist, wann das Promise erstellt wird. Hiermit können Sie Handler dem Erfolgswert oder dem Fehlergrund einer asynchronen Aktion zuordnen. Auf diese Weise können asynchrone Methoden Werte wie synchrone Methoden zurückgeben: Anstelle des endgültigen Werts gibt die asynchrone Methode das Versprechen zurück, irgendwann in der Zukunft einen Wert zu haben.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Die deferred.promise() -Methode ermöglicht eine asynchrone Funktion, um zu verhindern, dass anderer Code den Fortschritt oder den Status seiner internen Anforderung beeinträchtigt. Das Promise macht nur die Deferred-Methoden verfügbar, die zum Anfügen zusätzlicher Handler oder zum Bestimmen des Status (, Fertig, Fehler, Immer, Pipe, Fortschritt, Status und Versprechen erforderlich sind. ), aber nicht diejenigen, die den Status ändern ( auflösen, ablehnen, benachrichtigen, auflösen mit, ablehnen mit und benachrichtigen mit ).

Wenn target angegeben ist, hängt deferred.promise() die Methoden an und gibt dieses Objekt zurück, anstatt ein neues zu erstellen. Dies kann nützlich sein, um das Promise-Verhalten an ein bereits vorhandenes Objekt anzuhängen.

Wenn Sie eine Zurückgestellte erstellen, behalten Sie einen Verweis auf die Zurückgestellte bei, damit diese zu einem bestimmten Zeitpunkt aufgelöst oder abgelehnt werden kann. Geben Sie über deferred.promise () nur das Promise-Objekt zurück, damit andere Codes Rückrufe registrieren oder den aktuellen Status überprüfen können.

Wir können einfach sagen, dass ein Versprechen einen Wert darstellt, der noch nicht bekannt ist, wo als Aufgeschoben steht für noch nicht abgeschlossene Arbeiten.


enter image description here

29
IRSHAD
  • Ein promise repräsentiert einen Wert, der noch nicht bekannt ist
  • Ein deferred steht für noch nicht abgeschlossene Arbeiten

Ein Versprechen ist ein Platzhalter für ein anfangs unbekanntes Ergebnis, während ein Zurückgestelltes die Berechnung darstellt, die den Wert ergibt.

Referenz

22
mattLummus