В моем приложении Angular.js я выполняю асинхронную операцию. Перед запуском я накрываю приложение модальным div, а затем, когда операция завершена, мне нужно удалить div, независимо от того, была ли операция успешной или нет.
В настоящее время у меня есть это:
LoadingOverlay.start();
Auth.initialize().then(function() {
LoadingOverlay.stop();
}, function() {
LoadingOverlay.stop(); // Code needs to be duplicated here
})
Он работает хорошо, однако я бы предпочел иметь что-то более чистое, например этот псевдокод:
LoadingOverlay.start();
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
LoadingOverlay.stop();
})
Я предполагаю, что это довольно распространенная проблема, поэтому я думал, что это можно сделать, но ничего не нашел в документе. Есть идеи, можно ли это сделать?
then()
, то вы можете , конечно , цепь другого ....initialize().then(...).then(...)
. Нет никакого «наконец» как такового; последний обработчик указан последним.initialize()
неудачи вам все равно нужно объявить как функцию «успеха», так и функцию «сбой», а также дублировать код..then()
- см. «API обещаний» здесь . Единственная свобода - иметь один.then()
или объединять несколько.then()
s. Вы не первый, кто желает иметь более обширный API обещаний - здесь официально запрашивается желаемая функция .always(callback)
не реализовано или откатано в angular 1.2.6. Надо использоватьfinally
сейчас. Интересно, почему зарезервированное словоfinally
лучше чемalways
.Ответы:
Эта функция была реализована в этом запросе на перенос и теперь является частью AngularJS. Первоначально он назывался «всегда», а затем переименован в
finally
, поэтому код должен быть следующим:LoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).finally(function() { // Always execute this on both error and success });
Обратите внимание, что, поскольку
finally
это зарезервированное ключевое слово, может потребоваться сделать его строкой, чтобы она не ломалась в определенных браузерах (например, IE и браузере Android):$http.get('/foo')['finally'](doSomething);
источник
always
но она была изменена на,finally
как вы можете видеть в этом коммите (или в источнике): github.com/angular/angular.js/commit/…finally
возвращает обещание, как и все остальные, так что вы можете связать его. Однако (по крайней мере, в некоторых версиях Angular) удобство перегружаетсяsuccess
иerror
добавляется только к немедленному возврату$http
, поэтому, если вы начнете с,finally
вы потеряете эти методы.Я использую серверную часть Umbraco версии 7.3.5 с AngularJS версии 1.1.5 и нашел эту ветку. Когда я реализовал утвержденный ответ, я получил ошибку:
Однако то, что работало, было
always
. Если кто-то другой, использующий старую версию AngularJS, найдет этот поток и не можетfinally
использовать этот код вместо этогоLoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).always(function() { // Always execute this on both error and success });
источник
Для тех, кто не использует angularJS, и если у вас все в порядке с обнаружением ошибки (не уверен, что .finally () сделает это), вы можете использовать .catch (). Then (), чтобы избежать дублирования кода.
Promise.resolve() .catch(() => {}) .then(() => console.log('finally'));
В любом случае catch () может оказаться полезным для ведения журнала или другой очистки. https://jsfiddle.net/pointzerotwo/k4rb41a7/
источник
Я бы использовал ngView для рендеринга содержимого страницы и запуска удаления модального окна в событии $ viewContentLoaded. См http://docs.angularjs.org/api/ng.directive:ngView для этого события и http://docs.angularjs.org/api/ng . $ RootScope.Scope за $ на слушателя событий.
источник