Während des Schreibens von Node.js können kontinuierliche IO -Operationen zu "Pyramid -Albtraum" führen. Die mehrfache Verschachtelung von Rückruffunktionen erschwert den Code. Das Versprechen von CommonJS wird verwendet, um asynchrone Funktionen zu verkapulieren und eine einheitliche Ketten -API zu verwenden, um den Albtraum mehrerer Rückrufe loszuwerden.
Mit dem von Node.js bereitgestellten nicht blockierenden IO-Modell können wir Rückruffunktionen zur Ausführung von IO-Vorgängen verwenden. Wenn jedoch kontinuierliche IO-Vorgänge erforderlich sind, sind Ihre Rückruffunktionen mehrmals verschachtelt, der Code ist nicht schön, und es ist nicht leicht zu pflegen, und es gibt viele wiederholte Codes für die Fehlerhandlung, die sogenannte Pyramid "pyramid" -Pyramid "von Doomid".
Die Codekopie lautet wie folgt:
STEP1 (Funktion (value1) {
STEP2 (value1, Funktion (value2) {
STEP3 (value2, function (value3) {
Schritt 4 (value3, function (value4) {
// etwas mit value4 mach4
});
});
});
});
Dies ist eigentlich das Problem des Kontrollflusss in Node.js. Es gibt viele Lösungen für dieses Problem, z. B. die Verwendung von Async, EventProxy usw. Das Thema dieses Artikels besteht jedoch darin, Versprechen in der CommonJS -Spezifikation zur Lösung dieses Problems zu verwenden.
Was ist vielversprechend?
Es gibt viele Arten von Versprechenspezifikationen für CommonJs. Wir diskutieren im Allgemeinen die Versprechen/A+ -Pezifikation, die das grundlegende Verhalten des Versprechens definiert.
Ein Versprechen ist ein Objekt, das normalerweise eine asynchrone Operation darstellt, die in Zukunft möglicherweise abgeschlossen sein kann. Diese Operation kann erfolgreich sein oder scheitern, sodass ein Versprechensobjekt im Allgemeinen 3 Staaten hat: anhängig, erfüllt und abgelehnt. Es repräsentiert unvollendete, erfolgreiche Abschluss bzw. Betriebsfehler. Sobald sich der Zustand des Versprechensobjekts von anhängig zu erfüllt oder abgelehnt ändert, kann sein Zustand nicht erneut geändert werden.
Ein Versprechensobjekt hat normalerweise eine damalige Methode, mit der wir den nach möglichen Erfolg in der Zukunft zurückgegebenen Wert oder den Grund für ein Scheitern bedienen können. Diese dann sieht diese Methode so aus:
Versprechen.
Es ist offensichtlich, dass die damalige Methode zwei Parameter akzeptiert, die normalerweise zwei Funktionen sind. Eine wird verwendet, um das Ergebnis nach dem Erfolg des Betriebs zu verarbeiten, und die andere wird verwendet, um die Ursache des Betriebsausfalls zu verarbeiten. Die ersten Parameter dieser beiden Funktionen sind das Ergebnis nach dem Erfolg und die Ursache des Versagens. Wenn die dann keine Funktion ist, wird dieser Parameter ignoriert.
Der Rückgabewert der damaligen Methode ist ein vielversprechendes Objekt, mit dem wir aufrufen können, um den Effekt der Kontrolle des Prozesses zu erreichen. Hier finden Sie viele Details, wie z. B. Wertübertragung oder Fehlerbehandlung. Die Versprechenspezifikation ist so definiert:
Der Rückgabewert der überfüllten oder onrejected -Funktion ist kein Versprechensobjekt, dann wird der Wert als erster Parameter der in der nächsten damaligen Methode. Wenn der Rückgabewert ein vielversprechendes Objekt ist, wie kann der Rückgabewert der damaligen Methode das Versprechensobjekt sein
Wenn eine Ausnahme in die aufgelöste oder aufgerichtete Funktion geworfen wird, wird der Status der damaligen Methode zurückgegebene Versprechensobjekt in abgelehnt umgewandelt. Wenn das Versprechenobjekt dann aufruft, wird das Fehlerobjekt als erster Parameter der Onrejected -Funktion verwendet.
Wenn der Versprechungsstatus erfüllt wird und die von der Stadion erfüllte Funktion nicht erfüllt ist, wird der von der damalige Methode zurückgegebene Versprechen -Objektzustand und das erfolgreiche Ergebnis das Ergebnis des vorherigen Versprechens, dasselbe gilt für abgelehnte.
Um hinzuzufügen, werden sowohl überfüllte als auch onrejected asynchron ausgeführt.
Implementierung der Spezifikation: q
In der oben genannten Spezifikation des Versprechens geht es um die Umsetzung. Q ist eine Bibliothek mit besseren Implementierungsspezifikationen für Versprechen/A+.
Zunächst müssen wir ein Versprechenobjekt erstellen. Die Spezifikationen für die Schaffung von Verheißungsobjekten sind in Versprechen/b. Ich werde hier nicht ausführlich erklären, fügen Sie einfach den Code hinzu.
Die Codekopie lautet wie folgt:
Funktion (Flag) {
var defer = q.Defer ();
fs
if (err) defer.reject (err);
sonst defer.resolve (Daten);
});
return defer.promise;
}
Die meisten versprochenen Implementierungen sind bei der Erstellung von Versprechen ähnlich. Durch das Erstellen eines Defer -Objekts mit Promise -Attribut wird, wenn der Wert erfolgreich erhalten wird, auf Verschiebung. Resolve (Wert) wird aufgerufen, wenn er fehlschlägt. Dieser Prozess kann als Aufruf von Defer verstanden werden.
Wie können Sie bei einer Reihe kontinuierlicher asynchroner Methoden mit Versprechen einen schönen Code schreiben? Schauen Sie sich das folgende Beispiel an.
Die Codekopie lautet wie folgt:
Promise0.then (Funktion (Ergebnis) {
// Dosen etwas
Rückgabeergebnis;
}). Dann (Funktion (Ergebnis) {
// Dosen etwas
Return Promise1;
}). Dann (Funktion (Ergebnis) {
// Dosen etwas
}). catch (function (ex) {
console.log (ex);
}). schließlich (function () {
console.log ("final");
});
Im obigen Code akzeptiert die damalige Methode nur die Vereinbarung, und die Catch -Methode ist dann tatsächlich (null, onrejected). Auf diese Weise wird der Code in einem Wasserfallstil, solange eine Reihe asynchroner Methoden immer erfolgreich erfolgreich zurückgegeben werden. Wenn eine der asynchronen Methoden fehlschlägt oder eine Ausnahme auftritt, wird nach der CommonJS -Versprechenspezifikation die Funktion im Fang ausgeführt. Q bietet auch eine schließlich Methode, die wörtlich leicht zu verstehen ist, dh, ob es sich umlöst oder ablehnt, wird die Funktion schließlich ausgeführt.
Es sieht gut aus, der Code ist mehr gepflegt und schön. Was ist also, wenn Sie Parallelität wollen?
Die Codekopie lautet wie folgt:
Q.All ([Promise0, Promise1, Promise2]). Spread (Funktion (Val0, Val1, Val2) {
console.log (Argumente);
}). Dann (function () {
console.log ("fone");
}). catch (function (err) {
console.log (err);
});
Q bietet auch eine API für die Parallelität, wenn Sie alle Methoden aufrufen und ein Versprechen -Array übergeben können, kann den Kettenstil von damals weiterhin verwenden. Es gibt auch gute Dinge wie Q.nfbind usw., die die native API von Node.js in das Versprechen umwandeln können, das Codeformat zu vereinen. Weitere APIs werden hier nicht ausführlich beschrieben.
abschließend
In diesem Artikel wird hauptsächlich die Verwendung von Versprechen vorgestellt EMCAscript6 hat native API -Unterstützung geliefert. Es sollte darauf hingewiesen werden, dass Versprechen nicht die einzige Lösung ist. Async ist auch eine gute Wahl und bietet eine freundlichere API für die Gleichzeitverkehrskontrolle, aber ich denke, dass Versprechen mehr Vorteile hat, wenn sie Funktionen mit asynchronen Methoden verknüpfen.
Okay, das ist alles für diesen Artikel, ich hoffe, es wird für alle hilfreich sein.