2013-04-16 7 views
77

В моем приложении Angular.js я запускаю некоторую асинхронную операцию. Перед запуском я охватываю приложение модальным div, а затем, как только операция будет завершена, мне нужно удалить div, была ли операция успешной или нет.Как всегда запускать некоторый код, когда обещание выполняется в Angular.js

В настоящее время у меня есть это:

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(); 
}) 

я предполагаю, что это довольно распространенная проблема, так Я думал, что это можно сделать, но ничего не может найти в доке. Любая идея, если это можно сделать?

+0

Если вы можете связать один 'then()', то вы можете с уверенностью связать другой ... '.initialize(). Then (...). Then (...)'. Там нет «наконец»; последний обработчик указан последним. –

+2

@ Beetroot-Beetroot, это не сработает, потому что если 'initialize()' fail, вам все равно нужно объявить как функцию «success», так и функцию «fail» и дублировать код там. –

+0

Не будет работать, или просто неэлегантно? –

ответ

148

Эта функция была реализована в 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 Browser):

$http.get('/foo')['finally'](doSomething); 
+9

Для тех, кто нашел это в веб-поиске, ссылка в ответе ссылалась на функцию 'always', но она была изменена на' finally', как вы можете видеть в этой фиксации (или в источнике): https: // github. com/angular/angular.js/commit/f078762d48d0d5d9796dcdf2cb0241198677582c –

+0

@AustinThompson, спасибо за информацию, я обновил сообщение. –

+0

@ this.lau_ действительно ли finally() должен быть последним вызовом в цепочке, или я могу больше связать() s от него? – Brian

7

Я использую Umbraco версии 7.3.5 задняя часть с AngularJS версии 1.1.5 и нашел эту тему. Когда я реализовал утвержденный ответ, который я получил ошибку:

xxx(...).then(...).finally is not a function

Что сделал работу, однако был always. Если кто-то использует старую версию AngularJS находит эту нить и не могут использовать finally использовать этот код вместо

LoadingOverlay.start(); 
Auth.initialize().then(function() { 
    // Success handler 
}, function() { 
    // Error handler 
}).always(function() { 
    // Always execute this on both error and success 
}); 
0

Для тех, не использующих angularJS, и если вы нормально с ловлей ошибки (не уверена, если. finally() сделает это), вы можете использовать .catch(). then(), чтобы избежать дублирования кода.

Promise.resolve() 
    .catch(() => {}) 
    .then(() => console.log('finally')); 

Уловка() может оказаться полезной в любом случае для ведения журнала или другой очистки. https://jsfiddle.net/pointzerotwo/k4rb41a7/

 Смежные вопросы

  • Нет связанных вопросов^_^