Überspringungskette nach Fehlerbehandlung

8

Mit der Ссылка -Bibliothek frage ich mich, ob es möglich ist, so etwas zu tun:

%Vor%

Wenn die Serviceergebnisse schlecht sind, würde ich gerne den Fehler in Modul A behandeln, indem ich eine Logik verwende, die spezifisch für die Interna von Modul A ist, aber die verbleibenden Modul B-Funktionen in der Versprechenskette überspringe.

Die offensichtliche Lösung für das Überspringen von Modul B-Funktionen besteht darin, einen Fehler / Grund von Modul A zu werfen. Allerdings müsste ich das in Modul B behandeln. Und im Idealfall würde ich es ohne zusätzlichen Code machen wollen Modul B dafür.

Was sehr wahrscheinlich unmöglich sein kann :) Oder gegen einige Designprinzipien von Q.

Welche Art von Alternativen würden Sie in diesem Fall vorschlagen?

Ich habe zwei Ansätze im Hinterkopf, aber beide haben ihre Nachteile:

  1. Wirf einen spezifischen Fehler von Modul A und füge spezifischen Modulationscode zu Modul B hinzu:

    %Vor%
  2. Führen Sie die benutzerdefinierte Fehlerbehandlung in Modul A aus, und werfen Sie nach dem Behandeln des Fehlers einen falschen Ablehnungsgrund ab. Fügen Sie in Modul B eine Bedingung hinzu, um den falschen Grund zu ignorieren:

    %Vor%

Lösung 1 erfordert das Hinzufügen von Modul A spezifischen Code zu Modul B.

Lösung 2 löst das, aber der ganze Ansatz der falschen Zurückweisung scheint sehr hackisch zu sein.

Können Sie andere Lösungen empfehlen?

    
mjomble 22.06.2014, 21:35
quelle

3 Antworten

1

Inspiriert von Benjamin Gruenbaums Kommentaren und Antworten - wenn ich dies im synchronen Code schreiben würde, würde ich moduleA_exportedFunction return a shouldContinue boolean machen.

Also, mit Versprechungen, würde es im Grunde so etwas sein (Disclaimer: das ist pseudo-code-ish und ungetestet)

%Vor%

In Modul B ist zwar ein gewisser Code erforderlich, aber die Logik ist weder spezifisch für die Interna von Modul A, noch beinhaltet sie das Werfen und Ignorieren gefälschter Fehler - Mission erfüllt! :)

    
mjomble 22.06.2014, 23:02
quelle
15

Sprechen wir über Kontrollkonstrukte.

In JavaScript wird Code beim Aufrufen einer Funktion auf zwei Arten ausgeführt.

  • Es kann return einem Wert für den Aufrufer geben, der anzeigt, dass es erfolgreich abgeschlossen wurde.
  • Es kann throw ein Fehler für den Aufrufer sein, was darauf hinweist, dass ein Ausnahmevorgang aufgetreten ist.

Es sieht ungefähr so ​​aus:

%Vor%

Versprechen modellieren genau dasselbe Verhalten.

In Promises wird der Code beim Aufruf einer Funktion in einem .then -Handler auf genau zwei Arten ausgeführt:

  • Es kann return ein Versprechen oder ein Wert sein, der anzeigt, dass es erfolgreich abgeschlossen wurde.
  • Es kann throw ein Fehler sein, der anzeigt, dass ein Ausnahmezustand aufgetreten ist.

Es sieht ungefähr so ​​aus:

%Vor%

Verspricht den Modellfluss der Steuerung selbst

Ein Versprechen ist eine Abstraktion über den Begriff Sequenzierungsoperationen selbst. Es beschreibt, wie die Kontrolle von einer Anweisung zur anderen übergeht. Sie können .then eine Abstraktion über ein Semikolon betrachten.

Sprechen wir über synchronen Code

Lassen Sie uns sehen, wie synchroner Code in Ihrem Fall aussehen würde.

%Vor%

Also, wie geht es weiter mit dem Rest unseres Codes ist einfach returning . Dies ist derselbe in synchronem Code und in asynchronem Code mit Versprechungen. Das Ausführen einer sehr spezifischen Fehlerbehandlung ist ebenfalls in Ordnung.

Wie würden wir den Rest des Codes in der synchronen Version überspringen?

%Vor%

Nun, auch wenn nicht sofort, ist ein ziemlich einfacher Weg, doD niemals auszuführen, indem man doC veranlasst, in eine Endlosschleife einzutreten:

%Vor%

Es ist also möglich, niemals ein Versprechen zu lösen - wie es die andere Antwort nahe legt - ein ausstehendes Versprechen zurückzugeben. Dies ist jedoch eine extrem schlechte Flusssteuerung, da die Absicht dem Verbraucher schlecht vermittelt wird und es wahrscheinlich sehr schwer zu debuggen ist. Stellen Sie sich die folgende API vor:

  

moduleA_exportedFunction - Diese Funktion erstellt eine API-Anforderung und gibt den Dienst als ServiceData -Objekt zurück, wenn die Daten verfügbar sind. Andernfalls wird das Programm in eine Endlosschleife eingefügt.

Ein bisschen verwirrend, nicht wahr :)? Es existiert jedoch tatsächlich an einigen Orten. Es ist nicht ungewöhnlich, das Folgende in wirklich alten APIs zu finden.

  

some_bad_c_api () - Diese Funktion enthält einen Balken, bei wird der Prozess beendet.

Was stört uns, den Prozess in dieser API trotzdem zu beenden?

Es geht um Verantwortung.

  • Es liegt in der Verantwortung der aufgerufenen API zu vermitteln, ob die API-Anfrage erfolgreich war.
  • Es liegt in der Verantwortung des Anrufers zu entscheiden, was in jedem Fall zu tun ist.

In Ihrem Fall. ModelA verletzt einfach die Grenzen seiner Verantwortung, es sollte nicht berechtigt sein , solche Entscheidungen über den Fluss des Programms zu treffen. Wer es konsumiert, sollte diese Entscheidungen treffen.

Werfen

Die bessere Lösung ist es, einen Fehler zu werfen und den Verbraucher damit umgehen zu lassen. Ich werde Bluebird-Versprechungen hier verwenden, da sie nicht nur zwei Größenordnungen schneller sind und eine viel modernere API haben - sie auch haben viel viel bessere Debugging-Möglichkeiten - in diesem Fall - Zucker für bedingte Fänge und bessere Stack-Traces:

%Vor%

Also in einer Zeile - Sie würden tun, was Sie in synchronem Code tun würden, wie es bei Versprechungen normalerweise der Fall ist.

Hinweis: Promise.method ist nur eine Komfortfunktion, die Bluebird für die Funktionen des Wrappings hat. Ich hasse synchrone Argumente für die Rückgabe von APIs, da es zu größeren Brüchen führt.

    
Benjamin Gruenbaum 22.06.2014 22:17
quelle
2

Es ist eine Art Designsache. Wenn ein Modul oder Dienst eine Zusage zurückgibt, möchten Sie im Allgemeinen, dass der Aufruf erfolgreich war und andernfalls fehlschlägt. Wenn das Versprechen weder auflöst noch fehlschlägt, obwohl Sie wissen, dass der Aufruf fehlgeschlagen ist, handelt es sich im Grunde genommen um einen stillen Fehler.

Aber hey, ich kenne die Einzelheiten Ihrer Module oder Gründe nicht. Wenn Sie also in diesem Fall stillschweigend versagen wollen, können Sie dies tun, indem Sie ein nicht gelöstes Versprechen zurückgeben:

// Modul A

%Vor%     
David McMullin 22.06.2014 21:42
quelle

Tags und Links