Как всегда запускать некоторый код, когда обещание выполняется в Angular.js
В моем приложении 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();
})
Я предполагаю, что это довольно распространенная проблема, поэтому я думал, что это можно сделать, но ничего не может найти в документе. Любая идея, если это можно сделать?
Ответы
Ответ 1
Эта функция была реализована в this pull request и теперь является частью 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);
Ответ 2
Я использую Umbraco версии 7.3.5 с помощью EndularJS версии 1.1.5 и нашел эту тему. Когда я выполнил одобренный ответ, я получил сообщение об ошибке:
xxx (...), затем (...). наконец, не является функцией
Однако работа была always
. Если кто-либо другой, использующий старую версию AngularJS, находит этот поток и не может использовать finally
, используйте этот код вместо
LoadingOverlay.start();
Auth.initialize().then(function() {
// Success handler
}, function() {
// Error handler
}).always(function() {
// Always execute this on both error and success
});
Ответ 3
Я бы использовал ngView для рендеринга содержимого страницы и инициировал удаление модальности события $viewContentLoaded. См. http://docs.angularjs.org/api/ng.directive:ngView для этого события и http://docs.angularjs.org/api/ng. $rootScope.Scope для прослушивателя событий $on.
Ответ 4
Для тех, кто не использует angularJS, и если вы в порядке с улавливанием ошибки (не уверен, что если .finally() сделает это), вы можете использовать .catch(). then(), чтобы избежать дублирования кода.
Promise.resolve()
.catch(() => {})
.then(() => console.log('finally'));
Ловушка() может оказаться полезной в любом случае для ведения журнала или другой очистки.
https://jsfiddle.net/pointzerotwo/k4rb41a7/