2015-03-16 13 views
8

Guardando un sacco di video Egghead.io, ho notato che uno schema comune è quello di restituire una promessa personalizzata e risolverla nei callback.

.factory('myFact', function($q, $http) { 
    return { 
     getData: function() { 
      var deferred = $q.defer(); 
      $http.get('/path/to/api') 
       .success(function(data) { 
        deferred.resolve(data); 
       }); 
      return deferred.promise; 
     } 
    }; 
}); 

che normalmente scrivo questo come:

.factory('myFact', function($http) { 
    return { 
     getData: function() { 
      return $http.get('/path/to/api') 
       .then(function(res) { 
        return res.data; 
       }); 
     } 
    }; 
}); 

C'è qualche vantaggio di restituire una promessa $q.defer() piuttosto che un $http promessa? Gli approcci sembrano identici a me.

+2

Considererei questo [deferred antipattern] (https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern); tuttavia, elimina il tuo bisogno di conoscere l'oggetto '$ http' dal controller (cioè, non hai bisogno di conoscere i dati che vuoi effettivamente sia' response.data', non solo 'data') – Tom

+1

il modo in cui fai normalmente è molto meglio e più pulito, non vedo alcun vantaggio nel percorrere la seconda via. '$ http' restituisce già una promessa, perché crearne una nuova? – Nobita

+0

Stai aggiungendo una promessa risolta a una promessa risolta, è solo ridondante. $ q.defer() è più per cose che non hanno già una promessa. – ribsies

risposta

3

No, alcun vantaggio, è lo stesso, Nel vostro primo codice tagliò si è creato un'istanza $q.defer() poi è stato richiamato il suo metodo resolve() per creare una promessa risolto.

Questo è il processo è necessario conoscere e superare un tiro in angularJs quando si lavora con funziona in modo asincrono e oggetti futuro che avrà valori diversi o nuovi dati in qualche momento futuro che è necessario sapere quando accade perché le parti interessate nella tua app potrebbero aver bisogno di accedere al risultato dell'attività differita al termine.

Ora, quando si lavora con $http non devi fare nulla di tutto ciò, perché sarà già restituito un risolto promessa che si può direttamente invocarlo è then() metodo a meno che non si dispone di un modo diverso di fare le cose ed è necessario implementare un approccio diverso.

Ma non tutti i servizi di angularJs stanno andando a fare il lavoro per voi, dare un'occhiata a $resource per esempio, che avvolge $http per l'utilizzo in scenari API web RESTful. $resource non restituirà un risolto promessa, una promessa sì, hai trovato uno, ma è necessario fare l'ultimo passo di risolverla (check this stack question o this e forse this article about Amber Kaplan's own experience working with Rest).

Quindi il modo in cui si sta facendo è buono, è così che lo sto facendo anche quando lavoro con $http ma il primo codice snippet è quello che cercheremo tutti quando avremo bisogno di fare le cose in modo diverso con $http o forzando altri servizi a 'funziona con' o 'funziona come' AJAX.

Problemi correlati