app.js
Option 1 - Pause/ca ncel die Versprechenskette
Eine kleine Änderung im HttpInterceptor
kann dazu dienen, die Versprechenskette zu brechen/abzubrechen, was bedeutet, dass weder activateOk
noch activateError
auf dem Controller ausgeführt werden.
function HttpInterceptor($q, $location) {
var service = {
responseError: responseError
};
return service;
function responseError(rejection) {
if (rejection.status === 404) {
$location.path('/error');
return $q(function() { return null; })
}
return $q.reject(rejection);
}
}
Die Linie return $q(function() { return null; })
, bricht das Versprechen.
Ob dies "ok" ist, ist ein Thema der Debatte. Kyle Simpson in „You don't know JS“ heißt es:
Viele Versprechen Abstraktion Bibliotheken Einrichtungen bieten Versprechen zu stornieren, aber das ist eine schreckliche Idee!Viele Entwickler wünschen Promises hatte ursprünglich mit externen Stornierungsfähigkeit entwickelt worden, aber das Problem ist, dass es einen Verbraucher/Beobachter eines Promise beeinflussen könnte einige andere Verbraucher die Fähigkeit, das gleiche Versprechen zu beobachten. Dies verstößt gegen die Vertrauenswürdigkeit des future-value (externe Unveränderlichkeit), aber morever ist die Verkörperung der "Fernwirkung" anti-Muster ...
gut? Schlecht? Wie gesagt, es ist ein Diskussionsthema. Ich mag die Tatsache, dass es keine Änderungen an bestehenden $http
Verbraucher erfordert.
Kyle hat ganz recht, wenn er sagt:
Viele Versprechen Abstraktion Bibliotheken Einrichtungen bieten Versprechen zu stornieren ...
Die Drossel Versprechen Bibliothek zum Beispiel hat die Unterstützung für den Abbruch. Von the documentation:
Die neue Stornierung hat „do not care“ Semantik, während die alte Löschung Semantik hatte abbrechen. Das Abbrechen eines Versprechens bedeutet einfach , dass seine Handler-Callbacks nicht aufgerufen werden.
Option 2 - Eine andere Abstraktion
Promises sind eine relativ breite Abstraktion. Vom Promises/A+ specification:
Ein Versprechen stellt das schließliche Ergebnis eines asynchronen Betrieb.
Der Winkel $http
Dienst verwendet die $q
Umsetzung der Versprechen ein Versprechen für das schließliche Ergebnis einer asynchronen HTTP-Anforderung zurückzukehren.
Es lohnt sich nichts, was $http
two deprecated functions, .success
und .error
, die das zurückgegebene Versprechen dekorieren hat. 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 das zugrundeliegende Versprechen offen legt, das von $http
verwendet wird. Wie folgt aus:
function HttpWrapper($http, $location) {
var service = {
get: function (getUrl, successCallback, errorCallback) {
$http.get(getUrl).then(function (response) {
successCallback(response);
}, function (rejection) {
if (rejection.status === 404) {
$location.path('/error');
} else {
errorCallback(rejection);
}
});
}
};
return service;
}
sein, dass dies nicht ein Versprechen nicht zurückgibt, muss der Verbrauch ein wenig anders arbeiten:
HttpWrapper.get('non-existent-location', getSuccess, getError);
function getSuccess(response) {
alert('Everything is ok');
}
function getError(error) {
alert('An error happened');
}
Im Falle eines 404 wird die Lage geändert zu " Fehler ', 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? Ergebnisse können variieren...
Option 3 - Verzieren die Ablehnung
Credit TJ für seinen Kommentar:
, wenn Sie die Fehlerbehandlung in einem bestimmten Controller benötigen, werden Sie Bedingungen benötigen ein Fehler zu überprüfen, ob behandelt wurde in Interceptor/Service etc.
Der HTTP Interceptor kann das Versprechen Ablehnung mit einer Eigenschaft handled
dekorieren, ob i, um anzuzeigen, t's hat den Fehler behandelt.
function HttpInterceptor($q, $location) {
var service = {
responseError: responseError
};
return service;
function responseError(rejection) {
if (rejection.status === 404) {
$location.path('/error');
rejection.handled = true;
}
return $q.reject(rejection);
}
}
dann Regler wie folgt aussieht:
$http.get('non-existent-location')
.then(function activateOk(response) {
alert('Everything is ok');
})
.catch(function activateError(error) {
if (!error.handled) {
alert('An error happened');
}
});
Zusammenfassung
Anders als Option 2 Option 3 bleibt aber die Möglichkeit für jeden $http
Verbraucher Kette verspricht, was sich positiv in dem Sinne ist, dass es die Funktionalität nicht eliminiert.
Beide Optionen 2 und 3 haben weniger "Fernwirkung". Im Fall von Option 2 macht die alternative Abstraktion deutlich, dass sich die Dinge anders verhalten als die übliche Implementierung. Und für Option 3 erhält der Verbraucher das Versprechen, mit ihm zu tun, wie es ihm gefällt.
Alle 3 Optionen erfüllen die Wartbarkeitskriterien, da Änderungen an der globalen Fehlerbehandlungsroutine für mehr oder weniger Szenarien keine Änderungen an den Konsumenten erfordern.
Ich habe mich das gefragt, aber dann habe ich es vergessen. Danke, dass du mich daran erinnerst, es herauszufinden: D –