En mi aplicación Angular.js, estoy ejecutando una operación asincrónica. Antes de que comience, cubro la aplicación con un div modal, luego, una vez que se completa la operación, necesito eliminar el div, ya sea que la operación haya sido exitosa o no.
Actualmente tengo esto:
LoadingOverlay.start();
Auth.initialize().then(function() {
LoadingOverlay.stop();
}, function() {
LoadingOverlay.stop(); // Code needs to be duplicated here
})
Funciona bien, sin embargo, preferiría tener algo más limpio como este pseudocódigo:
LoadingOverlay.start();
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
LoadingOverlay.stop();
})
Supongo que es un problema bastante común, así que estaba pensando que se podría hacer pero no puedo encontrar nada en el documento. ¿Alguna idea de si se puede hacer?
then()
, entonces seguramente puede encadenar otra ....initialize().then(...).then(...)
. No existe un "finalmente" como tal; el controlador final es el último especificado.initialize()
falla, aún necesita declarar una función de "éxito" y una función de "falla" y el código duplicado allí..then()
consulte "La API de promesa" aquí . La única libertad es tener uno.then()
o encadenar varios.then()
s. No es el primero en desear una API de promesa más extensa: la función que desea se solicita formalmente aquí .always(callback)
no está implementado o revertido en angular 1.2.6. Tenemos que usarfinally
ahora. Me pregunto por qué la palabra reservadafinally
es mejor quealways
.Respuestas:
La función se implementó en esta solicitud de extracción y ahora es parte de AngularJS. Inicialmente se llamó "siempre" y luego se le cambió el nombre a
finally
, por lo que el código debería ser el siguiente:LoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).finally(function() { // Always execute this on both error and success });
Tenga en cuenta que, dado que
finally
es una palabra clave reservada, podría ser necesario convertirla en una cadena para que no se rompa en ciertos navegadores (como IE y el navegador de Android):$http.get('/foo')['finally'](doSomething);
fuente
always
pero se cambió afinally
como puede ver en esta confirmación (o en la fuente): github.com/angular/angular.js/commit/…finally
devuelve una promesa como el resto, para que puedas encadenarla. Sin embargo (al menos en algunas versiones de Angular) la conveniencia se sobrecargasuccess
yerror
solo se agrega al retorno inmediato de$http
, por lo que si comienza confinally
, perderá esos métodos.Estoy usando el back-end de la versión 7.3.5 de Umbraco con la versión 1.1.5 de AngularJS y encontré este hilo. Cuando implementé la respuesta aprobada, recibí el error:
Sin embargo, lo que funcionó fue
always
. Si alguien más que usa una versión anterior de AngularJS encuentra este hilo y no puedefinally
usar este código en su lugarLoadingOverlay.start(); Auth.initialize().then(function() { // Success handler }, function() { // Error handler }).always(function() { // Always execute this on both error and success });
fuente
Para aquellos que no usan angularJS, y si está de acuerdo con detectar el error (no estoy seguro de si .finally () haría eso), podría usar .catch (). Then () para evitar el código duplicado.
Promise.resolve() .catch(() => {}) .then(() => console.log('finally'));
El catch () podría terminar siendo útil de todos modos para el registro u otra limpieza. https://jsfiddle.net/pointzerotwo/k4rb41a7/
fuente
Usaría ngView para representar el contenido de la página y activar la eliminación de su modal en el evento $ viewContentLoaded. Consulte http://docs.angularjs.org/api/ng.directive:ngView para ese evento y http://docs.angularjs.org/api/ng . $ RootScope.Scope para el detector de eventos $ on.
fuente