J'ai un service i18n dans mon application qui contient le code suivant:
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;
};
L'idée est que l'utilisateur appelle ensureLocaleIsLoaded
et attend que la promesse soit résolue. Mais étant donné que le but de la fonction est uniquement de s'assurer que la locale est chargée, il serait parfaitement normal que l'utilisateur l'invoque plusieurs fois.
Je suis actuellement en train de stocker une seule promesse et de la résoudre si l'utilisateur appelle à nouveau la fonction après que les paramètres régionaux ont été récupérés avec succès sur le serveur.
D'après ce que je peux dire, cela fonctionne comme prévu, mais je me demande si c'est une approche appropriée.
javascript
angularjs
Der Hochstapler
la source
la source
Réponses:
Si je comprends bien les promesses actuelles, cela devrait être parfait à 100%. La seule chose à comprendre est qu'une fois résolue (ou rejetée), c'est pour un objet différé - c'est fait.
Si vous devez appeler à nouveau
then(...)
sur sa promesse, vous devriez immédiatement obtenir le (premier) résultat résolu / rejeté.Les appels supplémentaires à
resolve()
n'auront pas (ne devraient pas?) Avoir d'effet. Je ne sais pas ce qui se passe si vous essayezreject
un objet différé qui était auparavantresolved
(je ne soupçonne rien).la source
J'ai fait face à la même chose il y a quelque temps, en effet une promesse ne peut être résolue qu'une fois, un autre essai ne fera rien (pas d'erreur, pas d'avertissement, pas d'
then
invocation).J'ai décidé de travailler comme ceci:
passez simplement votre fonction en rappel et invoquez-la autant de fois que vous le souhaitez! J'espère que cela a du sens.
la source
getUsers
et l'invoquer.then()
autant de fois que vous le souhaitez. Il n'est pas nécessaire de passer un rappel. À mon avis, l'un des avantages des promesses est que vous n'avez pas besoin de spécifier le rappel à l'avance..then
déclarations. Pour ce que cela vaut, je pense que la seule façon de renvoyer des données plusieurs fois au contexte appelant est d'utiliser des rappels et non des promesses, car les promesses n'ont pas été conçues pour fonctionner de cette manière.Si vous avez besoin de modifier la valeur de retour de la promesse, renvoyez simplement la nouvelle valeur
then
et enchaînez ensuitethen
/catch
dessusla source
Il n'y a pas de moyen clair de résoudre les promesses plusieurs fois, car depuis qu'elles sont résolues, c'est fait. La meilleure approche ici consiste à utiliser un modèle observable par l'observateur, par exemple, j'ai écrit le code suivant qui observe l'événement du client socket. Vous pouvez étendre ce code pour répondre à vos besoins
la source
Vous pouvez écrire des tests pour confirmer le comportement.
En exécutant le test suivant, vous pouvez conclure que
Vous pouvez également consulter mon article de blog pour plus de détails.
la source
Ce que vous devez faire est de mettre un ng-if sur votre ng-outlet principal et d'afficher un spinner de chargement à la place. Une fois que vos paramètres régionaux sont chargés, vous affichez la prise et laissez la hiérarchie des composants s'afficher. De cette façon, toute votre application peut supposer que les paramètres régionaux sont chargés et qu'aucune vérification n'est nécessaire.
la source