Tengo un servicio i18n en mi aplicación que contiene el siguiente código:
var i18nService = function() {
this.ensureLocaleIsLoaded = function() {
if( !this.existingPromise ) {
this.existingPromise = $q.defer();
var deferred = this.existingPromise;
var userLanguage = $( "body" ).data( "language" );
this.userLanguage = userLanguage;
console.log( "Loading locale '" + userLanguage + "' from server..." );
$http( { method:"get", url:"/i18n/" + userLanguage, cache:true } ).success( function( translations ) {
$rootScope.i18n = translations;
deferred.resolve( $rootScope.i18n );
} );
}
if( $rootScope.i18n ) {
this.existingPromise.resolve( $rootScope.i18n );
}
return this.existingPromise.promise;
};
La idea es que el usuario llame ensureLocaleIsLoaded
y espere a que se resuelva la promesa. Pero dado que el propósito de la función es solo garantizar que se cargue la configuración regional, estaría perfectamente bien que el usuario la invocara varias veces.
Actualmente solo estoy almacenando una única promesa y la resuelvo si el usuario vuelve a llamar a la función después de que la configuración regional se haya recuperado con éxito del servidor.
Por lo que puedo decir, esto está funcionando según lo previsto, pero me pregunto si es un enfoque adecuado.
javascript
angularjs
Der Hochstapler
fuente
fuente
Respuestas:
Según entiendo las promesas en la actualidad, esto debería estar bien al 100%. Lo único que hay que entender es que una vez resuelto (o rechazado), eso es todo para un objeto rechazado: está hecho.
Si debe
then(...)
volver a cumplir su promesa, debe obtener inmediatamente el (primer) resultado resuelto / rechazado.Las llamadas adicionales a
resolve()
no tendrán ningún efecto (¿no deberían?). No estoy seguro de qué sucede si intentareject
un objeto rechazado que fue previamenteresolved
(sospecho que nada).fuente
Me enfrenté a lo mismo hace un tiempo, de hecho, una promesa solo se puede resolver una vez, otros intentos no harán nada (sin error, sin advertencia, sin
then
invocación).Decidí solucionarlo así:
simplemente pase su función como una devolución de llamada e invocala tantas veces como desee. Espero que tenga sentido.
fuente
getUsers
y luego invocar.then()
esa promesa tantas veces como desee. No es necesario pasar una devolución de llamada. En mi opinión, una de las ventajas de las promesas es que no es necesario especificar la devolución de llamada por adelantado..then
declaraciones. Por lo que vale, creo que la única forma de devolver datos varias veces al contexto de llamada es usar devoluciones de llamada y no promesas, ya que las promesas no se crearon para funcionar de esa manera.Si es necesario cambiar el valor de retorno de la promesa, devuelva nuevo valor de
then
cadena y al ladothen
/catch
en élfuente
No hay una forma clara de resolver las promesas varias veces porque, dado que se resuelve, se hace. El mejor enfoque aquí es usar un patrón observable por el observador, por ejemplo, escribí el siguiente código que observa el evento del cliente de socket. Puede ampliar este código para satisfacer sus necesidades
fuente
Puede escribir pruebas para confirmar el comportamiento.
Al ejecutar la siguiente prueba, puede concluir que
También puede consultar la publicación de mi blog para obtener más detalles.
fuente
Lo que debe hacer es poner un ng-if en su salida ng principal y mostrar una ruleta de carga en su lugar. Una vez que se carga la configuración regional, muestra la salida y deja que la jerarquía de componentes se represente. De esta manera, toda su aplicación puede asumir que la configuración regional está cargada y no es necesario realizar comprobaciones.
fuente