Ich habe ES6 Promise verwendet.
Normalerweise wird ein Versprechen so konstruiert und verwendet
new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});
Aber ich habe etwas wie das Folgende getan, um die Entschlossenheit aus Gründen der Flexibilität nach draußen zu bringen.
var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});
Und später
onClick = function(){
outsideResolve();
}
Das funktioniert gut, aber gibt es einen einfacheren Weg, dies zu tun? Wenn nicht, ist dies eine gute Praxis?
javascript
promise
es6-promise
Morio
quelle
quelle
Promise
synchron ausgeführt werden muss, damit die beiden Funktionen "exportiert" werden können.Antworten:
Nein, es gibt keinen anderen Weg, dies zu tun - das einzige, was ich sagen kann, ist, dass dieser Anwendungsfall nicht sehr häufig ist. Wie Felix im Kommentar sagte - was Sie tun, wird konsequent funktionieren.
Es ist erwähnenswert, dass der Grund, warum sich der Versprechen-Konstruktor so verhält, die Wurfsicherheit ist. Wenn eine Ausnahme, die Sie nicht erwartet haben, auftritt, während Ihr Code im Versprechen-Konstruktor ausgeführt wird, wird dies zu einer Ablehnung, dieser Form der Wurfsicherheit - Konvertieren von geworfenen Fehlern in Ablehnungen sind wichtig und helfen dabei, vorhersehbaren Code beizubehalten.
Aus Gründen der Wurfsicherheit wurde der Versprechenskonstruktor gegenüber verzögerten Konstruktionen ausgewählt (dies ist eine alternative Versprechungskonstruktionsmethode, die das erlaubt, was Sie tun). Was Best Practices betrifft, würde ich das Element übergeben und stattdessen den Versprechungskonstruktor verwenden:
Aus diesem Grund - wann immer Sie können das Versprechen Konstruktor über den Export der Funktionen - Ich empfehle Ihnen , es zu verwenden. Wann immer Sie beides vermeiden können - vermeiden Sie beides und die Kette.
Beachten Sie, dass Sie den Versprechen-Konstruktor niemals für Dinge wie
if(condition)
das erste Beispiel verwenden sollten, das wie folgt geschrieben werden könnte:quelle
Promise
Kette aufrufen ? In meinem speziellen Fall bin ich beispielsweise auf einem Server und warte auf eine bestimmte Client-Antwort (ein SYN-ACK-Handshake, um sicherzustellen, dass der Client den Status erfolgreich aktualisiert hat).einfach:
quelle
promiseResolve()
. Die Semantik eines Versprechens ist, dass es immer einen Wert zurückgibt. Dies ist auch funktional das gleiche wie der Beitrag von OP. Ich verstehe nicht, welches Problem dies auf wiederverwendbare Weise löst.promiseResolve()
keine Ausnahme aus. Sie können ein.catch
auf dem Konstruktor definieren und unabhängig davon, welcher Code es aufruft, wird der Konstruktor.catch
aufgerufen. Hier ist die jsbin zeigen , wie dies funktioniert: jsbin.com/yicerewivo/edit?js,consoleEtwas spät zur Party hier, aber eine andere Möglichkeit wäre die Verwendung eines verzögerten Objekts. Sie haben im Wesentlichen die gleiche Menge an Boilerplate, aber es ist praktisch, wenn Sie sie weitergeben und möglicherweise außerhalb ihrer Definition auflösen möchten.
Naive Implementierung:
ES5-Version:
quelle
resolve|reject
lexikalisch oder durch zugewiesen werdenbind
. Dies ist nur eine einfache Implementierung des jQuery Deferred- Objekts, das es seit 1.0 (ish) gibt. Es funktioniert genau wie ein Versprechen, außer dass es keine Wurfsicherheit gibt. Der springende Punkt dieser Frage war, wie ein paar Codezeilen beim Erstellen von Versprechungen gespeichert werden können.Deferred
veraltet?Eine Lösung, die ich 2015 für mein Framework gefunden habe. Ich habe diese Art von Versprechen Aufgabe genannt
quelle
Ich mochte @ JonJaques Antwort, aber ich wollte noch einen Schritt weiter gehen.
Wenn Sie
then
undcatch
dann dasDeferred
Objekt binden , implementiert es diePromise
API vollständig und Sie können es als Versprechen behandeln undawait
es und so.quelle
Eine Hilfsmethode würde diesen zusätzlichen Aufwand verringern und Ihnen das gleiche jQuery-Gefühl vermitteln.
Verwendung wäre
Welches ist ähnlich wie jQuery
Obwohl in einem Anwendungsfall diese einfache, native Syntax in Ordnung ist
quelle
Ich benutze eine Hilfsfunktion, um ein "flaches Versprechen" zu erstellen -
Und ich benutze es so -
Vollständiges Arbeitsbeispiel anzeigen -
Code-Snippet anzeigen
Bearbeiten: Ich habe ein NPM-Paket namens Flat-Promise erstellt und der Code ist auch auf GitHub verfügbar .
quelle
Sie können das Versprechen in eine Klasse einschließen.
quelle
Viele der Antworten hier ähneln dem letzten Beispiel in diesem Artikel . Ich speichere mehrere Versprechen zwischen, und die Funktionen
resolve()
undreject()
können jeder Variablen oder Eigenschaft zugewiesen werden. Dadurch kann ich diesen Code etwas kompakter gestalten:Hier ist ein vereinfachtes Beispiel für die Verwendung dieser Version von
defer()
, um einFontFace
Ladeversprechen mit einem anderen asynchronen Prozess zu kombinieren :Update: 2 Alternativen für den Fall, dass Sie das Objekt kapseln möchten:
und
quelle
const result = await deferred.promise;
Akzeptierte Antwort ist falsch. Es ist ziemlich einfach, Umfang und Referenzen zu verwenden, obwohl es Promise- Puristen verärgern kann:
Wir greifen im Wesentlichen auf den Verweis auf die Auflösungsfunktion zurück, wenn das Versprechen erstellt wird, und geben dies zurück, damit es extern festgelegt werden kann.
In einer Sekunde gibt die Konsole Folgendes aus:
quelle
Ja, du kannst. Durch Verwendung der
CustomEvent
API für die Browserumgebung. Und Verwenden eines Event-Emitter-Projekts in node.js-Umgebungen. Da sich das fragliche Snippet auf die Browserumgebung bezieht, finden Sie hier ein funktionierendes Beispiel dafür.Ich hoffe diese Antwort ist nützlich!
quelle
Unsere Lösung bestand darin, Verschlüsse zum Speichern der Auflösungs- / Ablehnungsfunktionen zu verwenden und zusätzlich eine Funktion anzuhängen, um das Versprechen selbst zu erweitern.
Hier ist das Muster:
Und damit:
quelle
promise.resolve_ex = _resolve; promise.reject_ex = _reject;
... funktioniert immer noch gut.In bestimmten Fällen fehlt mir auch das verzögerte Muster. Sie können jederzeit eine über einem ES6-Versprechen erstellen:
quelle
Vielen Dank an alle, die in diesem Thread gepostet haben. Ich habe ein Modul erstellt, das das zuvor beschriebene Defer () -Objekt sowie einige andere darauf aufgebaute Objekte enthält. Sie alle nutzen Promises und die übersichtliche Promise-Rückrufsyntax, um die Kommunikation / Ereignisbehandlung in einem Programm zu implementieren.
Warteschlange: Ausführungswarteschlange basierend auf Promise-Verkettung.
rp = require("repeatable-promise")
https://github.com/CABrouwers/repeatable-promise
quelle
Ich habe dafür eine kleine Bibliothek geschrieben. https://www.npmjs.com/package/@inf3rno/promise.exposed
Ich habe andere den Factory - Methode Ansatz geschrieben, aber ich overrode die
then
,catch
,finally
zu Methoden, so können Sie das ursprüngliche Versprechen von denen auch lösen.Versprechen ohne Testamentsvollstrecker von außen lösen:
Rennen mit dem setTimeout des Testamentsvollstreckers von außen:
Es gibt einen konfliktfreien Modus, wenn Sie den globalen Namespace nicht verschmutzen möchten:
quelle
Ich habe eine Bibliothek namens erstellt
manual-promise
, die als Ersatz für fungiertPromise
. Keine der anderen Antworten hier funktioniert als ErsatzPromise
, da sie Proxys oder Wrapper verwenden.yarn add manual-promise
npn install manual-promise
https://github.com/zpxp/manual-promise#readme
quelle
Wie wäre es, eine Funktion zu erstellen, um die Zurückweisung zu entführen und zurückzugeben?
quelle
Ich habe eine Übersicht zusammengestellt, die diese Aufgabe erfüllt: https://gist.github.com/thiagoh/c24310b562d50a14f3e7602a82b4ef13
So sollten Sie es verwenden:
quelle
Aktivieren Sie zuerst die Syntax --allow-natives-im Browser oder Knoten
quelle
Nur eine weitere Lösung, um Promise von außen zu lösen
Verwendung
quelle