Hier ist, wie ich denke, dass Sie tun sollten.
die Kette teilen
Da beide Funktionen erstaunlichDaten verwenden , ist es sinnvoll, sie in einer dedizierten Funktion zu haben. Normalerweise mache ich das jedes Mal, wenn ich einige Daten wiederverwenden möchte, sodass sie immer als Funktionsargument vorhanden sind.
Da in Ihrem Beispiel Code ausgeführt wird, wird angenommen, dass alles in einer Funktion deklariert ist. Ich werde es toto () nennen . Dann haben wir eine weitere Funktion, die sowohl afterSomething () als auch afterSomethingElse () ausführt .
function toto() {
return somethingAsync()
.then( tata );
}
Sie werden auch feststellen, dass ich eine Rückgabeerklärung hinzugefügt habe , da dies normalerweise der richtige Weg für Versprechen ist. Sie geben immer ein Versprechen zurück, damit wir bei Bedarf weiter verketten können. Hier wird etwas Async () erstaunliche Daten erzeugen und es wird überall in der neuen Funktion verfügbar sein.
Wie diese neue Funktion aussehen wird, hängt normalerweise davon ab, ob processAsync () auch asynchron ist .
processAsync nicht asynchron
Kein Grund, Dinge zu komplizieren, wenn processAsync () nicht asynchron ist. Ein alter guter sequentieller Code würde es schaffen.
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Beachten Sie, dass es keine Rolle spielt, ob afterSomethingElse () etwas Asynchrones tut oder nicht. In diesem Fall wird ein Versprechen zurückgegeben und die Kette kann fortgesetzt werden. Ist dies nicht der Fall, wird der Ergebniswert zurückgegeben. Da die Funktion jedoch von then () aufgerufen wird , wird der Wert ohnehin in ein Versprechen eingeschlossen (zumindest in rohem Javascript).
processAsync asynchron
Wenn processAsync () asynchron ist, sieht der Code etwas anders aus. Hier betrachten wir, dass afterSomething () und afterSomethingElse () nirgendwo anders wiederverwendet werden.
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
/* amazingData can be accessed here */
}
}
Gleich wie zuvor für afterSomethingElse () . Es kann asynchron sein oder nicht. Ein Versprechen wird zurückgegeben oder ein Wert in ein gelöstes Versprechen eingewickelt.
Ihr Codierungsstil kommt dem, was ich mache, ziemlich nahe, deshalb habe ich auch nach 2 Jahren geantwortet. Ich bin kein großer Fan von anonymen Funktionen überall. Ich finde es schwer zu lesen. Auch wenn es in der Gemeinde durchaus üblich ist. Es ist so, als hätten wir die Rückruf-Hölle durch ein Versprechen-Fegefeuer ersetzt .
Ich halte auch gerne den Namen der Funktionen in der dann kurz. Sie werden sowieso nur lokal definiert. Und die meiste Zeit rufen sie eine andere Funktion auf, die an anderer Stelle definiert ist - also wiederverwendbar -, um die Arbeit zu erledigen. Ich mache das sogar für Funktionen mit nur 1 Parameter, so dass ich die Funktion nicht ein- und ausschalten muss, wenn ich der Funktionssignatur einen Parameter hinzufüge / entferne.
Beispiel essen
Hier ist ein Beispiel:
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
Konzentrieren Sie sich nicht zu sehr auf Promise.resolve () . Es ist nur ein schneller Weg, um ein gelöstes Versprechen zu erstellen. Was ich damit erreichen möchte, ist, den gesamten Code, den ich ausführe, an einem einzigen Ort zu haben - direkt unter den Thens . Alle anderen Funktionen mit einem aussagekräftigeren Namen können wiederverwendet werden.
Der Nachteil dieser Technik ist, dass sie viele Funktionen definiert. Aber ich fürchte, es ist ein notwendiger Schmerz, um zu vermeiden, überall anonyme Funktionen zu haben. Und was ist das Risiko überhaupt: ein Stapelüberlauf? (Scherz!)
Die Verwendung von Arrays oder Objekten, wie in anderen Antworten definiert, würde ebenfalls funktionieren. Dies ist in gewisser Weise die Antwort von Kevin Reid .
Sie können auch bind () oder Promise.all () verwenden . Beachten Sie, dass Sie weiterhin Ihren Code teilen müssen.
mit bind
Wenn Sie Ihre Funktionen wiederverwendbar halten wollen , aber nicht wirklich brauchen , zu halten , was im Inneren der ist dann sehr kurz, können Sie bind () .
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
Um es einfach zu halten, wird bind () der Liste der Argumente (mit Ausnahme der ersten) beim Aufruf vor die Funktion stellen.
mit Promise.all
In Ihrem Beitrag haben Sie die Verwendung von verbreiten () erwähnt . Ich habe das von Ihnen verwendete Framework nie verwendet, aber hier ist, wie Sie es verwenden können sollten.
Einige glauben, dass Promise.all () die Lösung für alle Probleme ist, daher sollte es wohl erwähnt werden.
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
Sie können Daten an Promise.all () übergeben - beachten Sie das Vorhandensein des Arrays - solange Versprechen vorliegen. Stellen Sie jedoch sicher, dass keines der Versprechen fehlschlägt, da sonst die Verarbeitung beendet wird.
Und anstatt neue Variablen aus dem Argument args zu definieren , sollten Sie in der Lage sein , pread () anstelle von then () für alle Arten von großartiger Arbeit zu verwenden.