2015-03-16 7 views
8

Bei vielen Egghead.io-Videos habe ich festgestellt, dass ein gängiges Muster darin besteht, ein benutzerdefiniertes Versprechen zurückzugeben und es in den Rückrufen zu lösen.

.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; 
     } 
    }; 
}); 

Ich würde dies in der Regel schreiben wie:

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

Gibt es einen Vorteil, ein $q.defer() Versprechen eher als ein $http Versprechen der Rückkehr? Die Ansätze sehen für mich identisch aus.

+2

Ich würde dies die [latente Antipattern] (https://github.com/petkaantonov/bluebird/wiki/Promise-anti-pattern#the-deferred-anti-pattern); Sie brauchen jedoch nichts über das '$ http'-Objekt vom Controller zu wissen (dh, Sie müssen nicht wissen, dass die Daten, die Sie eigentlich wollen,' response.data' sind, nicht nur 'data') – Tom

+1

Wie Sie normalerweise tun, ist viel besser und sauberer, ich sehe keinen Vorteil in der zweiten Route. '$ http' gibt bereits ein Versprechen zurück, warum ein neues erstellen? – Nobita

+0

Sie fügen einem aufgelösten Versprechen ein aufgelöstes Versprechen hinzu, das nur überflüssig ist. $ q.defer() ist mehr für Dinge, die nicht schon ein Versprechen haben. – ribsies

Antwort

3

Nein, keine Vorteile, ist es die gleiche, in Ihrem ersten Code snipped Sie eine $q.defer() Instanz erstellt dann aufgerufen Sie seine resolve() Methode ein aufgelösten Versprechen zu erstellen.

, dass der Prozess ist, müssen Sie wissen, und throw in AngularJS passieren, wenn mit Arbeits Funktionen asynchron und Zukunft Objekten, die unterschiedlichen Werte oder neue Daten zu einem späteren Zeitpunkt haben wird, die Sie wissen müssen wenn es passiert, weil Interessenten in Ihrer App möglicherweise Zugriff auf das Ergebnis der verzögerten Aufgabe erhalten müssen, wenn sie abgeschlossen ist.

Nun, wenn sie mit $http arbeiten Sie haben zu einem das nicht zu tun, weil es bereits ein aufgelöst Versprechen zurück, die Sie direkt aufrufen kann es then() Methode, wenn Sie eine andere Art und Weise, Dinge zu tun, und Sie müssen einen anderen Ansatz implementieren.

Aber nicht alle AngularJS Dienste die Arbeit für Sie tun werden, um einen Blick zu $resource zum Beispiel erhalten, die in RESTful Web-API-Szenarien $http zur Verwendung einwickelt. $resource wird nicht zurückkehrt ein aufgelösten Versprechen, ein Versprechen ja, Sie eine bekommen, aber Sie werden den letzten Schritt es zu lösen (check this stack question oder this und vielleicht this article about Amber Kaplan's own experience working with Rest) tun müssen.

Also die Art und Weise, wie Sie es tun ist gut, das ist, wie ich es auch bei der Arbeit mit $http aber der erste Code-Snippet ist derjenige, den wir alle suchen werden, wenn wir Dinge tun müssen anders mit $http oder zwingen andere Dienste zu 'arbeiten mit' oder 'funktionieren wie' AJAX.

Verwandte Themen