Ich möchte mit Versprechungen arbeiten, habe aber eine Rückruf-API in einem Format wie:
1. DOM-Last oder ein anderes einmaliges Ereignis:
window.onload; // set to callback
...
window.onload = function() {
};
2. Einfacher Rückruf:
function request(onChangeHandler) {
...
}
request(function() {
// change happened
...
});
3. Rückruf im Knotenstil ("Nodeback"):
function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})
4. Eine ganze Bibliothek mit Rückrufen im Knotenstil:
API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});
new Promise
zusätzlichen Overheads hinzu? Ich möchte alle meine synchronen Noje.js-Funktionen in ein Versprechen einbinden, um den gesamten synchronen Code aus meiner Node-App zu entfernen. Ist dies jedoch die beste Vorgehensweise? Mit anderen Worten, eine Funktion, die ein statisches Argument (z. B. eine Zeichenfolge) akzeptiert und ein berechnetes Ergebnis zurückgibt, sollte ich das in ein Versprechen einschließen? ... Ich habe irgendwo gelesen, dass Sie in Nodejs keinen synchronen Code haben sollten.Antworten:
Versprechen haben Status, sie beginnen als ausstehend und können sich mit folgenden Punkten zufrieden geben:
Versprechende Rückgabefunktionen sollten niemals ausgelöst werden , sondern stattdessen Ablehnungen zurückgeben. Wenn Sie eine Funktion zum Zurückgeben von Versprechungen deaktivieren, werden Sie gezwungen, sowohl a
} catch {
als auch a zu verwenden.catch
. Menschen, die vielversprechende APIs verwenden, erwarten keine Versprechen. Wenn Sie sich nicht sicher sind, wie asynchrone APIs in JS funktionieren, lesen Sie zuerst diese Antwort .1. DOM-Last oder ein anderes einmaliges Ereignis:
Das Erstellen von Versprechungen bedeutet also im Allgemeinen, anzugeben, wann sie sich niederlassen - das heißt, wann sie in die erfüllte oder abgelehnte Phase wechseln, um anzuzeigen, dass die Daten verfügbar sind (und mit denen zugegriffen werden kann
.then
).Mit modernen Versprechen-Implementierungen, die den
Promise
Konstruktor wie native ES6-Versprechen unterstützen:Sie würden dann das resultierende Versprechen wie folgt verwenden:
Mit Bibliotheken, die verzögert unterstützen (Verwenden wir hier $ q für dieses Beispiel, aber wir werden später auch jQuery verwenden):
Oder mit einer jQuery-ähnlichen API, die sich auf ein Ereignis einlässt, das einmal passiert:
2. Einfacher Rückruf:
Diese APIs sind ziemlich häufig, da Rückrufe in JS häufig vorkommen. Schauen wir uns den häufigen Fall von
onSuccess
und anonFail
:Mit modernen Versprechen-Implementierungen, die den
Promise
Konstruktor wie native ES6-Versprechen unterstützen:Mit Bibliotheken, die verzögert unterstützen (Verwenden wir hier für dieses Beispiel jQuery, aber wir haben oben auch $ q verwendet):
jQuery bietet auch ein
$.Deferred(fn)
Formular an, das den Vorteil hat, dass wir einen Ausdruck schreiben können, der dasnew Promise(fn)
Formular wie folgt sehr genau emuliert :Hinweis: Hier nutzen wir die Tatsache, dass die zurückgestellten
resolve
undreject
Methoden einer jQuery "abnehmbar" sind. dh. Sie sind an die Instanz einer jQuery.Deferred () gebunden . Nicht alle Bibliotheken bieten diese Funktion an.3. Rückruf im Knotenstil ("Nodeback"):
Rückrufe im Knotenstil (Nodebacks) haben ein bestimmtes Format, bei dem die Rückrufe immer das letzte Argument sind und der erste Parameter ein Fehler ist. Lassen Sie uns zunächst eine manuell versprechen:
Zu:
Mit Zurückgestellten können Sie Folgendes tun (verwenden wir Q für dieses Beispiel, obwohl Q jetzt die neue Syntax unterstützt, die Sie bevorzugen sollten ):
Im Allgemeinen sollten Sie Dinge nicht zu viel manuell versprechen. Die meisten Versprechungsbibliotheken, die unter Berücksichtigung von Node entwickelt wurden, sowie native Versprechungen in Node 8+ verfügen über eine integrierte Methode zum Versprechen von Nodebacks. Zum Beispiel
4. Eine ganze Bibliothek mit Rückrufen im Knotenstil:
Hier gibt es keine goldene Regel, Sie versprechen sie eins nach dem anderen. Bei einigen Versprechen-Implementierungen können Sie dies jedoch in großen Mengen tun, z. B. in Bluebird. Das Konvertieren einer Nodeback-API in eine Versprechen-API ist so einfach wie:
Oder mit einheimischen Versprechungen in Node :
Anmerkungen:
.then
Handler befinden, müssen Sie natürlich keine Dinge versprechen. Wenn Sie ein Versprechen von einem.then
Handler zurückgeben, wird es mit dem Wert dieses Versprechens aufgelöst oder abgelehnt. Das Werfen von einem.then
Handler ist ebenfalls eine gute Praxis und lehnt das Versprechen ab - dies ist das berühmte Versprechen, Sicherheit zu werfen.onload
Fall sollten SieaddEventListener
eher als verwendenonX
.quelle
resolve()
undreject()
geschrieben werden , wiederverwendbar ist, wage ich , dass meine vorgeschlagen bearbeiten relevant ist , weil es ein jQuery Beispiel für die Form bietet$.Deferred(fn)
, die sonst fehlt. Wenn nur ein jQuery-Beispiel enthalten ist, dann schlage ich vor, dass es eher von dieser Form als vonvar d = $.Deferred();
usw. sein sollte, da die Leute ermutigt werden sollten, die oft vernachlässigte$.Deferred(fn)
Form zu verwenden, und in einer Antwort wie dieser jQuery mehr auf eine Stufe mit Bibliotheken, die das Revealing Constructor Pattern verwenden .$.Deferred(fn)
. Wenn Sie das in den nächsten 15 Minuten anstelle des vorhandenen Beispiels bearbeiten, kann ich sicher versuchen, es rechtzeitig zu genehmigen :)util.promisify
, dass Node.js ab RC 8.0.0 zu seinem Kern hinzugefügt wird. Es funktioniert nicht viel anders als BluebirdPromise.promisify
, hat aber den Vorteil, dass keine zusätzlichen Abhängigkeiten erforderlich sind, falls Sie nur native Promise möchten. Ich habe einen Blog-Beitrag über util.promisify für alle geschrieben, die mehr über das Thema lesen möchten.Heute kann ich verwenden
Promise
inNode.js
als einfache JavaScript - Methode.Ein einfaches und grundlegendes Beispiel für
Promise
(mit KISS Weg):Einfacher Javascript Async API-Code:
Promise
Javascript Async API-Code:(Ich empfehle diese schöne Quelle zu besuchen )
Auch
Promise
kann mit zusammen verwendet werden ,async\await
in ,ES7
um den Programmablauf Wartezeit für ein machtfullfiled
Ergebnis wie folgt aus :Eine andere Verwendung mit demselben Code unter Verwendung der
.then()
MethodePromise
kann auch auf jeder Plattform verwendet werden, die auf Node.js wie basiertreact-native
.Bonus : Ein Hybridverfahren (Die Callback - Methode wird angenommen , zwei Parameter als Fehler und das Ergebnis haben)
Die obige Methode kann auf Ergebnisse für altmodische Rückruf- und Promise-Verwendungen reagieren.
Hoffe das hilft.
quelle
Vor dem Konvertieren einer Funktion als Versprechen In Node.JS
Nach dem Konvertieren
Falls Sie mehrere Anfragen bearbeiten müssen
quelle
Ich denke nicht, dass der
window.onload
Vorschlag von @Benjamin die ganze Zeit funktionieren wird, da er nicht erkennt, ob er nach dem Laden aufgerufen wird. Das hat mich schon oft gebissen. Hier ist eine Version, die immer funktionieren sollte:quelle
setTimeout(resolve, 0)
(odersetImmediate
, falls verfügbar) verwendet werden, um sicherzustellen, dass er asynchron aufgerufen wird?resolve
Synchron anrufen ist in Ordnung. Diethen
Handler des Promise werden durch das Framework garantiert, das asynchron aufgerufen wird , unabhängig davon, obresolve
es synchron aufgerufen wird.Node.js 8.0.0 enthält eine neue
util.promisify()
API, mit der Standard-APIs im Node.js-Rückrufstil in eine Funktion eingeschlossen werden können, die ein Versprechen zurückgibt. Ein Beispiel für die Verwendung vonutil.promisify()
ist unten gezeigt.Siehe Verbesserte Unterstützung für Versprechen
quelle
In Release Candidate für Node.js 8.0.0 gibt es ein neues Dienstprogramm
util.promisify
(ich habe über util.promisify geschrieben ), das die Fähigkeit enthält, jede Funktion zu versprechen.Es unterscheidet sich nicht wesentlich von den in den anderen Antworten vorgeschlagenen Ansätzen, hat jedoch den Vorteil, dass es eine Kernmethode ist und keine zusätzlichen Abhängigkeiten erfordert.
Dann haben Sie eine
readFile
Methode, die eine native zurückgibtPromise
.quelle
util.promisify
zweimal vorgeschlagen (im Jahr 2014, als diese Frage geschrieben wurde, und vor einigen Monaten - was ich als Kernmitglied von Node forciert habe und die aktuelle Version ist, die wir in Node haben). Da es noch nicht öffentlich verfügbar ist, habe ich es dieser Antwort noch nicht hinzugefügt. Wir würden uns jedoch sehr über Feedback zur Nutzung freuen und wissen, was einige Fallstricke sind, um bessere Dokumente für die Veröffentlichung zu haben :)util.promisify
in Ihrem Blog-Beitrag diskutieren :)util.promisify.custom
Symbol möglich ist, das Ergebnis von util.promisify zu überschreiben? Um ehrlich zu sein, war dies ein absichtlicher Fehler, da ich noch keinen nützlichen Anwendungsfall finden kann. Vielleicht kannst du mir ein paar Inputs geben?fs.exists
oder APIs, die nicht der Node-Konvention folgen - ein BluebirdPromise.promisify
würde sie falsch verstehen , aberutil.promisify
sie richtig machen.Sie können native JavaScript-Versprechen mit Node JS verwenden.
Mein Cloud 9-Code-Link: https://ide.c9.io/adx2803/native-promises-in-node
quelle
Mit einfachem altem Vanille-JavaScript ist hier eine Lösung, um einen API-Rückruf zu versprechen.
quelle
Die Q-Bibliothek von kriskowal enthält Callback-to-Promise-Funktionen. Eine Methode wie diese:
kann mit Q.ninvoke konvertiert werden
quelle
Q.denodeify
. Müssen wir Bibliothekshelfer hervorheben?Wenn Sie einige Funktionen haben, die einen Rückruf annehmen, und Sie möchten, dass sie stattdessen ein Versprechen zurückgeben, können Sie diese Funktion verwenden, um die Konvertierung durchzuführen.
quelle
Unter dem Knoten v7.6 +, der Versprechen und Asynchronität eingebaut hat:
Wie benutzt man:
quelle
In Node.js 8 können Sie promisify Objektmethoden on the fly mit diesem npm Modul:
https://www.npmjs.com/package/doasync
Es verwendet util.promisify und Proxies, damit Ihre Objekte unverändert bleiben. Das Auswendiglernen erfolgt auch mithilfe von WeakMaps. Hier sind einige Beispiele:
Mit Objekten:
Mit Funktionen:
Sie können sogar native verwenden
call
undapply
einen Kontext binden:quelle
Sie können natives Versprechen in ES6 verwenden, um beispielsweise setTimeout zu behandeln:
In diesem Beispiel hat das Versprechen keinen Grund zum Scheitern und wird daher
reject()
niemals genannt.quelle
Die Callback-Style- Funktion sieht immer so aus (fast alle Funktionen in node.js sind dieser Style):
Dieser Stil hat die gleiche Funktion:
Die Rückruffunktion wird vom letzten Argument übergeben.
Die Rückruffunktion akzeptiert immer das Fehlerobjekt als erstes Argument.
Sie könnten also eine Funktion zum Konvertieren einer Funktion mit diesem Stil wie folgt schreiben:
Für eine präzisere Darstellung wurde im obigen Beispiel ramda.js verwendet. Ramda.js ist eine hervorragende Bibliothek für die funktionale Programmierung. Im obigen Code haben wir Apply (wie Javascript
function.prototype.apply
) und Append (wie Javascriptfunction.prototype.push
) verwendet. Wir könnten also die Funktion a callback style jetzt in die Funktion function versprechen konvertieren:Die Funktion toPromise and checkErr gehört der Berserker- Bibliothek. Es handelt sich um eine funktionale Programmierbibliothek von ramda.js (von mir erstellt).
Hoffe, diese Antwort ist nützlich für Sie.
quelle
Sie können so etwas tun
Dann benutze es
quelle
es6-promisify
konvertiert Callback-basierte Funktionen in Promise-basierte Funktionen.Ref: https://www.npmjs.com/package/es6-promisify
quelle
Meine vielversprechende Version einer
callback
Funktion ist dieP
Funktion:Die
P
Funktion erfordert, dass die Rückrufsignatur sein musscallback(error,result)
.quelle
util.promisify(fn)
(err, value) => ...
sein muss, oder Sie müssen eine benutzerdefinierte definieren (siehe Benutzerdefinierte versprochene Funktionen). Vielen Dank, gute Catcha.var P = function (fn, ...args) { return new Promise((resolve, reject) => fn.call(this, ...args, (error, result) => error ? reject(error) : resolve(result))); };
würde das gleiche tun wie Sie und es ist viel einfacher.Im Folgenden wird beschrieben, wie eine Funktion (Callback-API) in ein Versprechen konvertiert werden kann.
quelle
Es ist ungefähr 5 Jahre zu spät, aber ich wollte hier meine Promesify-Version veröffentlichen, die Funktionen aus der Callbacks-API übernimmt und sie in Versprechen umwandelt
Schauen Sie sich diese sehr einfache Version hier an: https://gist.github.com/jdtorregrosas/aeee96dd07558a5d18db1ff02f31e21a
quelle