Ich möchte bestimmte $http
-Fehlerszenarien global abfangen und verhindern, dass Controller die Fehler selbst behandeln. Ich denke, dass ich einen HTTP-Interceptor brauche, aber ich bin mir nicht sicher, wie ich meine Controller davon abbringen kann, auch den Fehler zu behandeln.
Ich habe einen Controller wie folgt:
%Vor%Und ein HTTP-Interceptor wie folgt:
%Vor% Dies funktioniert, sofern der Browser zum Pfad '/ error' umleitet. Aber die Verheißung catch in HomeController
wird auch ausgeführt, und ich will das nicht.
Ich weiß, ich könnte HomeController
so codieren, dass es einen 404-Fehler ignoriert, aber das ist nicht pflegbar. Angenommen, ich modifiziere HttpInterceptor
, um auch 500 Fehler zu behandeln, müsste ich dann HomeController
erneut modifizieren (ebenso wie alle anderen Controller, die seither hinzugefügt wurden und $http
verwenden). Gibt es eine elegantere Lösung?
Eine kleine Änderung in HttpInterceptor
kann dazu dienen, die Versprechenskette zu unterbrechen / abzubrechen, was bedeutet, dass weder activateOk
noch activateError
auf dem Controller ausgeführt werden.
Die Zeile return $q(function () { return null; })
löscht das Versprechen.
Ob das "ok" ist, ist ein Diskussionsthema. Kyle Simpson in " Sie nicht kenne JS nicht "sagt:
Viele Promise Abstraktionsbibliotheken bieten Möglichkeiten zum Abbrechen Versprechen, aber das ist eine schreckliche Idee! Viele Entwickler wünschen Promises war ursprünglich mit externen Stornierungsmöglichkeiten entwickelt worden, aber das Problem ist, dass es einen Verbraucher / Beobachter eines Versprechens lassen würde die Fähigkeit eines anderen Verbrauchers beeinflussen, dasselbe Versprechen zu halten. Dies verletzt die Vertrauenswürdigkeit des Zukunftswertes (externe Unveränderbarkeit), aber mehr ist die Verkörperung der "Fernwirkung" Anti-Pattern ...
Gut? Schlecht? Wie gesagt, es ist ein Diskussionsthema. Ich mag die Tatsache, dass es keine Änderung an bestehenden $http
-Kunden erfordert.
Kyle hat recht, wenn er sagt:
Viele Promise-Abstraktionsbibliotheken bieten Möglichkeiten, Promises abzubrechen ...
Die Bluebird Promise-Bibliothek bietet beispielsweise Unterstützung für die Stornierung. Von der Dokumentation :
Die neue Kündigung hat "egal" Semantik während der alten Abbruch hatte Semantik abzubrechen. Ein Versprechen zu annullieren bedeutet einfach dass seine Handler Callbacks nicht aufgerufen werden.
Versprechen sind eine relativ breite Abstraktion. Aus der Promises / A + Spezifikation :
Ein Versprechen repräsentiert das mögliche Ergebnis einer asynchronen Operation.
Der Dienst Angular $http
verwendet die $q
-Implementierung von Versprechen, eine Zusage für das eventuelle Ergebnis einer asynchronen HTTP-Anforderung zurückzugeben.
Es ist nichts wert, dass $http
zwei veraltete Funktionen hat, .success
und .error
, die das zurückgegebene Versprechen schmücken. Diese Funktionen waren veraltet, weil sie nicht in der typischen Weise verkettet werden konnten, die Versprechungen sind, und es wurde angenommen, dass sie nicht viel Wert als eine "HTTP-spezifische" Menge von Funktionen hinzufügen.
Aber das soll nicht heißen, dass wir nicht unsere eigene HTTP-Abstraktion / Wrapper erstellen können, die nicht einmal die zugrundeliegende Verheißung, die von $http
verwendet wird, preisgibt. So:
Da dies kein Versprechen ist, muss auch sein Konsum etwas anders funktionieren:
%Vor% Im Fall von 404 wird die Position in 'error' geändert, und weder getSuccess
noch getError
Callbacks werden ausgeführt.
Diese Implementierung bedeutet, dass die Möglichkeit, HTTP-Anfragen zu ketten, nicht mehr verfügbar ist. Ist das ein akzeptabler Kompromiss? Die Ergebnisse können variieren ...
Dankeschön an TJ für seinen Kommentar:
Wenn Sie eine Fehlerbehandlung in einem bestimmten Controller benötigen, benötigen Sie Bedingungen, um zu prüfen, ob ein Fehler in Abfangjäger / Service usw.
Der HTTP-Interzeptor kann die Ablehnung des Versprechens mit einer Eigenschaft handled
dekorieren, um anzugeben, ob der Fehler behandelt wurde.
Controller sieht dann so aus:
%Vor% Im Gegensatz zu Option 2 bleibt bei Option 3 für alle $http
-Kunden die Option, Versprechen zu verketten, was insofern positiv ist, als dass die Funktionalität nicht eliminiert wird.
Beide Optionen 2 und 3 haben weniger "Fernwirkung". Im Falle von Option 2 macht die alternative Abstraktion deutlich, dass sich die Dinge anders verhalten als die übliche $q
Implementierung. Und für Option 3 wird der Verbraucher das Versprechen erhalten, mit ihm zu tun, wie es ihm gefällt.
Alle 3 Optionen erfüllen die Wartbarkeitskriterien, da Änderungen an der globalen Fehlerbehandlungsroutine, um mehr oder weniger Szenarien zu handhaben, keine Änderungen an den Konsumenten erfordern.
In diesem Artikel wird erläutert, wie Sie http-Aufrufe abfangen und verschiedene Vorgänge ausführen können. Einer von ihnen behandelt Fehler.
Eine kurze Kopie einfügen aus dem obigen Artikel ...
%Vor%Tags und Links angularjs