angularjs - with - Você pode resolver uma promessa angular antes de devolvê-la?




router title angular (4)

Como simplesmente retornar uma promessa pré-resolvida no Angular 1.x

Promessa resolvida:

return $q.when( someValue );    // angular 1.2+
return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6

Promessa rejeitada:

return $q.reject( someValue );

Eu estou tentando escrever uma função que retorna uma promessa. Mas há momentos em que as informações solicitadas estão disponíveis imediatamente. Eu quero envolvê-lo em uma promessa para que o consumidor não precise tomar uma decisão.

function getSomething(id) {
    if (Cache[id]) {
        var deferred = $q.defer();
        deferred.resolve(Cache[id]); // <-- Can I do this?
        return deferred.promise;
    } else {
        return $http.get('/someUrl', {id:id});
    }
}

E usá-lo assim:

somethingService.getSomething(5).then(function(thing) {
    alert(thing);
});

O problema é que o retorno de chamada não é executado para a promessa pré-resolvida. Isso é uma coisa legítima a fazer? Existe uma maneira melhor de lidar com essa situação?


Aqui está como eu normalmente faço isso se eu quiser realmente armazenar dados em cache em array ou objeto

app.factory('DataService', function($q, $http) {
  var cache = {};
  var service= {       
    getData: function(id, callback) {
      var deffered = $q.defer();
      if (cache[id]) {         
        deffered.resolve(cache[id])
      } else {            
        $http.get('data.json').then(function(res) {
          cache[id] = res.data;              
          deffered.resolve(cache[id])
        })
      }
      return deffered.promise.then(callback)
    }
  }

  return service

})

DEMO


Você esqueceu de inicializar o elemento Cache

function getSomething(id) {
    if (Cache[id]) {
        var deferred = $q.defer();
        deferred.resolve(Cache[id]); // <-- Can I do this?
        return deferred.promise;
    } else {
        Cache[id] = $http.get('/someUrl', {id:id});
        return Cache[id];
    }
}

Resposta curta: Sim, você pode resolver uma promessa AngularJS antes de devolvê-la e ela se comportará como você espera.

De plnkr.co/edit/OGO8T2M1fE3Mrgj2oozj?p=preview mas refatorado para trabalhar dentro do contexto do que foi originalmente solicitado (ou seja, uma chamada de função para serviço) e, na verdade, no site.

Dentro do serviço ...

function getSomething(id) {
    // There will always be a promise so always declare it.
    var deferred = $q.defer();
    if (Cache[id]) {
        // Resolve the deferred $q object before returning the promise
        deferred.resolve(Cache[id]); 
        return deferred.promise;
    } 
    // else- not in cache 
    $http.get('/someUrl', {id:id}).success(function(data){
        // Store your data or what ever.... 
        // Then resolve
        deferred.resolve(data);               
    }).error(function(data, status, headers, config) {
        deferred.reject("Error: request returned status " + status); 
    });
    return deferred.promise;

}

Dentro do controlador ....

somethingService.getSomething(5).then(    
    function(thing) {     // On success
        alert(thing);
    },
    function(message) {   // On failure
        alert(message);
    }
);

Eu espero que isso ajude alguém. Eu não achei as outras respostas muito claras.





promise