web-dev-qa-db-fra.com

Comment toujours exécuter du code lorsqu'une promesse est remplie dans Angular.js

Dans mon application Angular.js, j'exécute une opération asynchrone. Avant de commencer, je couvre l'application avec un div modal, puis une fois l'opération terminée, je dois supprimer le div, que l'opération ait abouti ou non.

Actuellement j'ai ceci:

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    LoadingOverlay.stop();
}, function() {
    LoadingOverlay.stop(); // Code needs to be duplicated here
})

Cela fonctionne bien, mais je préférerais avoir quelque chose de plus propre comme ce pseudo-code:

LoadingOverlay.start(); 
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
    LoadingOverlay.stop();
})

Je suppose que c'est un problème assez commun, donc je pensais que cela pourrait être fait mais je ne trouve rien dans la documentation. Toute idée si cela peut être fait?

83
laurent

La fonctionnalité a été implémentée dans cette demande d'extraction et fait maintenant partie d'AngularJS. Il a d'abord été appelé "toujours", puis renommé plus tard finally. Le code devrait donc être le suivant:

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

Notez que, puisque finally est un mot clé réservé, il peut être nécessaire d’en faire une chaîne afin qu’elle ne tombe pas en panne sur certains navigateurs (tels que IE et Android):

$http.get('/foo')['finally'](doSomething);
161
laurent

J'utilise la version 7.3.5 d'Umbraco avec AngularJS version 1.1.5 et j'ai trouvé ce fil. Lorsque j'ai mis en œuvre la réponse approuvée, j'ai eu l'erreur:

xxx (...). then (...). finalement n'est pas une fonction

Ce qui fonctionnait cependant était always. Si quelqu'un d'autre utilisant une ancienne version de AngularJS trouve ce fil et ne peut pas utiliser finally, utilisez plutôt ce code

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

Pour ceux qui n'utilisent pas angularJS, et si vous êtes d'accord avec l'erreur (vous ne savez pas si .finally () le ferait), vous pouvez utiliser .catch (). Then () pour éviter le code dupliqué.

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

Le catch () peut s'avérer utile pour la journalisation ou tout autre nettoyage. https://jsfiddle.net/pointzerotwo/k4rb41a7/

2
PointZeroTwo

Je voudrais utiliser ngView pour rendre le contenu de la page et déclencher la suppression de votre modal sur l'événement $ viewContentLoaded. Voir http://docs.angularjs.org/api/ng.directive:ngView pour cet événement et http://docs.angularjs.org/api/ng . $ rootScope.Scope pour l'écouteur d'événement $ on.

1
ocolot