W mojej aplikacji Angular.js wykonuję operację asynchroniczną. Zanim się zacznie, zakrywam aplikację modalnym divem, a po zakończeniu operacji muszę usunąć div, niezależnie od tego, czy operacja się powiodła, czy nie.
Obecnie mam to:
LoadingOverlay.start();
Auth.initialize().then(function() {
LoadingOverlay.stop();
}, function() {
LoadingOverlay.stop(); // Code needs to be duplicated here
})
Działa dobrze, ale wolałbym mieć coś czystszego, takiego jak ten pseudokod:
LoadingOverlay.start();
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
LoadingOverlay.stop();
})
Zakładam, że to dość powszechny problem, więc myślałem, że można to zrobić, ale nie mogę znaleźć niczego w dokumencie. Masz jakiś pomysł, czy można to zrobić?
then()
, a następnie można z pewnością przykuje inny ....initialize().then(...).then(...)
. Nie ma „wreszcie” jako takiego; ostatni program obsługi to ostatni określony.initialize()
zawiedzie, nadal musisz zadeklarować zarówno funkcję „sukcesu”, jak i funkcję „fail” i zduplikowany kod..then()
- zobacz „The Promise API” tutaj . Jedyną swobodą jest posiadanie jednego.then()
lub łączenie wielu.then()
s. Nie jesteś pierwszą osobą, która marzy o bardziej rozbudowanym interfejsie API obietnicy - żądana funkcja jest tutaj formalnie wymagana .always(callback)
nie jest zaimplementowany ani wycofany w kątowym 1.2.6. Musimy użyćfinally
teraz. Zastanawiam się, dlaczego zarezerwowane słowofinally
jest lepsze niżalways
.Odpowiedzi:
Ta funkcja została zaimplementowana w tym żądaniu ściągnięcia i jest teraz częścią AngularJS. Początkowo nazywano go „zawsze”, a później zmieniono na
finally
, więc kod powinien wyglądać następująco:LoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).finally(function() { // Always execute this on both error and success });
Zwróć uwagę, że ponieważ
finally
jest to zarezerwowane słowo kluczowe, może być konieczne utworzenie ciągu, aby nie zepsuł się w niektórych przeglądarkach (takich jak IE i Android):$http.get('/foo')['finally'](doSomething);
źródło
always
ale zostało zmienione na,finally
jak widać w tym zatwierdzeniu (lub w źródle): github.com/angular/angular.js/commit/ ...finally
zwraca obietnicę tak jak reszta, więc możesz ją połączyć . Jednak (przynajmniej w niektórych wersjach Angulara) wygoda jest przeciążonasuccess
ierror
są dodawane tylko do natychmiastowego powrotu$http
, więc jeśli zaczniesz odfinally
, stracisz te metody.Używam zaplecza Umbraco w wersji 7.3.5 z AngularJS w wersji 1.1.5 i znalazłem ten wątek. Po zaimplementowaniu zatwierdzonej odpowiedzi otrzymałem błąd:
Jednak to, co zadziałało
always
. Jeśli ktoś inny używający starej wersji AngularJS znajdzie ten wątek i nie możefinally
użyć tego koduLoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).always(function() { // Always execute this on both error and success });
źródło
Dla tych, którzy nie używają angularJS i jeśli nie przeszkadza ci wychwycenie błędu (nie jesteś pewien, czy .finally () to zrobi), możesz użyć .catch (). Then (), aby uniknąć zduplikowanego kodu.
Promise.resolve() .catch(() => {}) .then(() => console.log('finally'));
Metoda catch () może i tak okazać się przydatna do logowania lub innego czyszczenia. https://jsfiddle.net/pointzerotwo/k4rb41a7/
źródło
Użyłbym ngView do wyrenderowania zawartości strony i spowodowania usunięcia twojego modalu w zdarzeniu $ viewContentLoaded. Zobacz http://docs.angularjs.org/api/ng.directive:ngView dla tego zdarzenia i http://docs.angularjs.org/api/ng . $ RootScope.Scope dla nasłuchiwania $ on event.
źródło