Pergunta

Estou trabalhando em um aplicativo administrativo com AngularJS.O aplicativo busca seus dados do servidor usando $resource.Acabo com objetos de dados contendo a propriedade '$promise' para determinar quando os dados foram obtidos.Está tudo bem.

Agora, este aplicativo administrativo também pode criar novos objetos.Esses novos objetos são gerenciados pelos mesmos controladores que normalmente vêm de '$resource'.

Então agora tenho 2 tipos de objetos:

  • Objetos com propriedade $promise.Eu deveria usar $promise.then() antes de manipulá-los com dados completos
  • Objetos simples.Eles não têm uma propriedade $promise, seu valor é acessível instantaneamente

Gostaria de reduzir o código e ter um único caso de uso, não precisando verificar se os dados do objeto estão resolvidos ou se não é uma promessa.

Existe algum problema em construir meus objetos 'simples' adicionando-lhes uma propriedade '$promise' que já está resolvida para eles mesmos?Dessa forma, eu sempre usaria 'myObject.$promise.then()'.

Existe algum padrão comum para lidar com esta situação?Não consegui encontrar nenhum método 'padrão' para criar esse tipo de objeto com Angular.

Foi útil?

Solução

Você poderia usar $q.quando se não tiver certeza se o objeto tem uma promessa ou não.

(obj.$promise ? obj.$promise || $q.when(objResult)).then(function(result){
          //handle success case.
          //Incase of object not having the $promise property result will be object itself
}) 

se a propriedade resultante não tiver uma promessa, isso será resolvido com promessa.

Agrupa um objeto que pode ser um valor ou uma promessa (de terceiros) então capaz em uma promessa $q.Isso é útil quando você está lidando com um objeto que pode ou não ser uma promessa, ou se a promessa vier de uma fonte na qual não se pode confiar.

Você não precisa sempre criar uma promessa e anexá-la aos dados que estão sendo transferidos; em vez disso, você pode fazer com que seus métodos retornem uma promessa, ajudando assim a implementar o padrão de promessa e abstrair a lógica da promessa em seu próprio serviço.Exemplo:-

   function getCurrentUserData(userId){
       var defered = $q.defer();
       ... 
       //Check in my cache if this is already there, then get it from cache and resolve it
       defered.resolve(objectFromCache);
      //my else condition
      //It is not in cache so let me make the call.
      $http.get('myurl').then(function(result){
            //Do validation with data and if it doesnot match then reject it
            defered.reject(reason);
             //Else Do something with the data put it into the cache, mapping logic etc..
             defered.resolve(dto);


      }).catch(function(error){
            //do something with error and then reject
            defered.reject(reasonDerived);
      });
      return defered.promise;
   }

Aqui está uma versão simplificada e menos explícita (Crédito:Benjamim Gruenbaum):

var cached = null;
function getCurrentUserData(userId){
    return cached = cached || $http.get('myurl').then(function(result){
        if(isNotValid(result)) return $q.reject(reason); // alternatively `throw`
        return transformToDto(result);
    }, function(response){
     if(checkforsomethingonstatusandreject)
       return $q.reject('Errored Out')
     //do some actions to notify the error scenarios and return default actions
     return someDefaults; });
    }

Você pode, é claro return $q.reject(derivedReason) aqui, em vez de retornar o motivo e transformá-lo com base em verificações adicionais, a ideia é armazenar em cache a promessa e não o valor.Isso também tem a vantagem de não fazer várias solicitações http se o método for chamado antes de retornar uma vez.

Agora você sempre pode fazer: -

    getCurrentUserData(userid).then(function(user){

    }).catch(function(error){

    });

As promessas também podem ser encadeadas.Então você também pode fazer isso: -

   return $resource('myresource').$promise.then(function(result){
          //Do some mapping and return mapped data
         return mappedResult;
    });

Outras dicas

As promessas A+ devem oferecer um método estático:

Promise.resolve(val);

...o que gera uma promessa pré-resolvida.Você deve devolver um destes se sua biblioteca de promessas oferecer isso.Ótimo.Faço isso com frequência para evitar duplicação de interface.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top