Em meu aplicativo Angular.js, estou executando algumas operações assíncronas. Antes de começar, abordo o aplicativo com um div modal e, depois que a operação for concluída, preciso remover o div, quer a operação tenha sido bem-sucedida ou não.
Atualmente eu tenho este:
LoadingOverlay.start();
Auth.initialize().then(function() {
LoadingOverlay.stop();
}, function() {
LoadingOverlay.stop(); // Code needs to be duplicated here
})
Funciona bem, mas prefiro algo mais limpo como este pseudo-código:
LoadingOverlay.start();
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
LoadingOverlay.stop();
})
Presumo que seja um problema bastante comum, por isso pensei que poderia ser feito, mas não consigo encontrar nada no documento. Alguma ideia se isso pode ser feito?
then()
, então você certamente pode encadear outra ....initialize().then(...).then(...)
. Não existe "finalmente" como tal; o manipulador final é o último especificado.initialize()
falhar, você ainda precisa declarar uma função de "sucesso" e uma função de "falha" e duplicar o código lá..then()
- consulte "A API de promessa" aqui . A única liberdade é ter um.then()
ou encadear vários.then()
s. Você não é o primeiro a desejar uma API de promessa mais abrangente - o recurso que deseja é formalmente solicitado aqui .always(callback)
não é implementado ou revertido no angular 1.2.6. Temos que usarfinally
agora. Eu me pergunto por que a palavra reservadafinally
é melhor do quealways
.Respostas:
O recurso foi implementado nesta solicitação pull e agora faz parte do AngularJS. Ele foi inicialmente chamado de "sempre" e depois renomeado para
finally
, portanto, o código deve ser o seguinte:LoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).finally(function() { // Always execute this on both error and success });
Observe que, por
finally
ser uma palavra-chave reservada, pode ser necessário transformá-la em uma string para que não quebre em certos navegadores (como o IE e o Android):$http.get('/foo')['finally'](doSomething);
fonte
always
mas foi alterado parafinally
como você pode ver neste commit (ou na fonte): github.com/angular/angular.js/commit/…finally
retorna uma promessa como o resto, então você pode encadear. No entanto (pelo menos em algumas versões do Angular) a conveniência sobrecarregasuccess
eerror
só são adicionadas ao retorno imediato de$http
, portanto, se você começar com,finally
perderá esses métodos.Estou usando o back-end do Umbraco versão 7.3.5 com AngularJS versão 1.1.5 e encontrei este tópico. Quando implementei a resposta aprovada, obtive o erro:
O que funcionou, entretanto, foi
always
. Se alguém mais usando uma versão antiga do AngularJS encontrar este tópico e não puder usar,finally
use este códigoLoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).always(function() { // Always execute this on both error and success });
fonte
Para aqueles que não usam angularJS, e se você não tem problemas em detectar o erro (não tenho certeza se .finally () faria isso), você poderia usar .catch (). Then () para evitar o código duplicado.
Promise.resolve() .catch(() => {}) .then(() => console.log('finally'));
O catch () pode acabar sendo útil de qualquer maneira para registro ou outra limpeza. https://jsfiddle.net/pointzerotwo/k4rb41a7/
fonte
Eu usaria o ngView para renderizar o conteúdo da página e acionar a remoção de seu modal no evento $ viewContentLoaded. Consulte http://docs.angularjs.org/api/ng.directive:ngView para esse evento e http://docs.angularjs.org/api/ng . $ RootScope.Scope para o ouvinte $ on event.
fonte