Tenho um serviço i18n em meu aplicativo que contém o seguinte 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;
};
A ideia é que o usuário ligasse ensureLocaleIsLoaded
e esperasse o cumprimento da promessa. Mas, dado que o propósito da função é apenas garantir que o local seja carregado, seria perfeitamente normal que o usuário a chamasse várias vezes.
No momento, estou apenas armazenando uma única promessa e resolvo isso se o usuário chamar a função novamente depois que a localidade for recuperada com êxito do servidor.
Pelo que posso dizer, está funcionando conforme o esperado, mas estou me perguntando se essa é uma abordagem adequada.
javascript
angularjs
Der Hochstapler
fonte
fonte
Respostas:
Pelo que entendi as promessas no momento, isso deve ser 100% bom. A única coisa a entender é que uma vez resolvido (ou rejeitado), isso é para um objeto adiado - está feito.
Se você ligar
then(...)
para a promessa novamente, você deve obter imediatamente o (primeiro) resultado resolvido / rejeitado.Chamadas adicionais para
resolve()
não terão (não deveriam?) Ter qualquer efeito. Não tenho certeza do que acontece se você tentarreject
um objeto adiado que era anteriormenteresolved
(não suspeito de nada).fonte
Eu enfrentei a mesma coisa há um tempo, na verdade uma promessa só pode ser resolvida uma vez, outras tentativas não farão nada (nenhum erro, nenhum aviso, nenhuma
then
invocação).Decidi contornar assim:
apenas passe sua função como um retorno de chamada e invoque quantas vezes desejar! Espero que isso faça sentido.
fonte
getUsers
e invocar.then()
essa promessa quantas vezes quiser. Não há necessidade de passar um retorno de chamada. Na minha opinião, uma das vantagens das promessas é que você não precisa especificar o retorno de chamada antecipadamente..then
instruções. Pelo que vale a pena, acho que a única maneira de retornar dados várias vezes para o contexto de chamada é usar retornos de chamada e não promessas, já que as promessas não foram criadas para funcionar dessa maneira.Se você precisar alterar o valor de retorno da promessa, simplesmente retorne o novo valor
then
e encadeie a seguirthen
/catch
nelefonte
Não há uma maneira clara de resolver as promessas várias vezes porque, uma vez que está resolvido, está feito. A melhor abordagem aqui é usar o padrão observável pelo observador, por exemplo, eu escrevi a seguir o código que observa o evento do cliente de soquete. Você pode estender este código para atender às suas necessidades
fonte
Você pode escrever testes para confirmar o comportamento.
Executando o seguinte teste, você pode concluir que
Você também pode verificar minha postagem do blog para obter detalhes.
fonte
O que você deve fazer é colocar um ng-if na saída principal do ng e mostrar um botão giratório de carregamento. Depois que sua localidade for carregada, você mostra a saída e deixa a hierarquia do componente renderizar. Dessa forma, todo o seu aplicativo pode assumir que a localidade está carregada e nenhuma verificação é necessária.
fonte