Ich habe gerade angefangen, Node zu verwenden, und eine Sache, die mir schnell aufgefallen ist, ist, wie schnell sich Rückrufe zu einem albernen Einrückungsgrad aufbauen können:
doStuff(arg1, arg2, function(err, result) {
doMoreStuff(arg3, arg4, function(err, result) {
doEvenMoreStuff(arg5, arg6, function(err, result) {
omgHowDidIGetHere();
});
});
});
Der offizielle Styleguide besagt, dass jeder Rückruf in eine separate Funktion gestellt werden soll. Dies scheint jedoch die Verwendung von Verschlüssen zu stark einzuschränken und ein einzelnes Objekt, das in der obersten Ebene deklariert ist, mehrere Ebenen tiefer verfügbar zu machen, da das Objekt alle durchlaufen muss Zwischenrückrufe.
Ist es in Ordnung, den Funktionsumfang zu verwenden, um hier zu helfen? Fügen Sie alle Rückruffunktionen, die Zugriff auf ein globales Objekt benötigen, in eine Funktion ein, die dieses Objekt deklariert, damit es geschlossen wird.
function topLevelFunction(globalishObject, callback) {
function doMoreStuffImpl(err, result) {
doMoreStuff(arg5, arg6, function(err, result) {
callback(null, globalishObject);
});
}
doStuff(arg1, arg2, doMoreStuffImpl);
}
und so weiter für mehrere weitere Schichten ...
Oder gibt es Frameworks usw., mit denen die Einrückungsstufen reduziert werden können, ohne für jeden einzelnen Rückruf eine benannte Funktion zu deklarieren? Wie gehen Sie mit der Rückrufpyramide um?
quelle
Antworten:
Es gibt mehrere Implementierungen von "Versprechungen":
Beispielsweise können Sie diese verschachtelten Rückrufe neu schreiben
mögen
Anstelle eines Rückrufs im Rückruf
a(b(c()))
verketten Sie das ".then"a().then(b()).then(c())
.Eine Einführung hier: http://howtonode.org/promises
quelle
Als Alternative zu Versprechungen sollten Sie sich das
yield
Schlüsselwort in Kombination mit Generatorfunktionen ansehen, die in EcmaScript 6 eingeführt werden. Beide sind heute in Node.js 0.11.x-Builds verfügbar, erfordern jedoch, dass Sie--harmony
beim Ausführen von Node zusätzlich das Flag angeben .js:Wenn Sie diese Konstrukte und eine Bibliothek wie TJ Holowaychuks co verwenden , können Sie asynchronen Code in einem Stil schreiben, der wie synchroner Code aussieht , obwohl er immer noch asynchron ausgeführt wird. Grundsätzlich implementieren diese Dinge zusammen die Co-Routine-Unterstützung für Node.js.
Grundsätzlich müssen Sie eine Generatorfunktion für den Code schreiben, der asynchrones Material ausführt, das dortige asynchrone Material aufrufen, ihm jedoch das
yield
Schlüsselwort voranstellen . Am Ende sieht Ihr Code also so aus:Um diese Generatorfunktion auszuführen, benötigen Sie eine Bibliothek wie die zuvor erwähnte co. Der Anruf sieht dann so aus:
Oder, um es inline zu setzen:
Bitte beachten Sie, dass Sie von den Generatorfunktionen aus andere Generatorfunktionen aufrufen können. Sie müssen ihnen lediglich
yield
erneut ein Präfix voranstellen .Um eine Einführung in dieses Thema zu erhalten, durchsuchen Sie Google nach Begriffen wie
yield generators es6 async nodejs
und Sie sollten unzählige Informationen finden. Es dauert eine Weile, bis man sich daran gewöhnt hat, aber wenn man es einmal hat, will man nie mehr zurück.Bitte beachten Sie, dass Sie dadurch nicht nur eine bessere Syntax zum Aufrufen von Funktionen erhalten, sondern auch die üblichen (synchronen) Steuerflusslogikfunktionen wie
for
Schleifen odertry
/ verwenden könnencatch
. Kein Herumspielen mehr mit vielen Rückrufen und all diesen Dingen.Viel Glück und hab Spaß :-)!
quelle
Sie haben jetzt das Paket asyncawait mit einer sehr engen Syntax für die zukünftige native Unterstützung von
await
&async
in Node.Grundsätzlich können Sie asynchronen Code schreiben, der synchron aussieht, wodurch die LOC- und Einrückungsstufen drastisch reduziert werden, wobei ein geringfügiger Leistungsverlust zu erwarten ist (die Anzahl der Paketinhaber beträgt 79% Geschwindigkeit im Vergleich zu unformatierten Rückrufen), der hoffentlich reduziert wird, wenn native Unterstützung verfügbar ist.
Immer noch eine gute Wahl, um aus der Callback-Hölle / Pyramide des Schicksals-Alptraums IMO herauszukommen, wenn Leistung nicht das Hauptanliegen ist und der synchrone Schreibstil besser zu den Anforderungen Ihres Projekts passt.
Grundlegendes Beispiel aus dem Paket doc:
quelle