2016-06-28 31 views
11

Obecnie używam $ usługę q od kątowe do wykonywania połączeń API jak to:

var deferred = $q.defer(); 
$http.get(config.apiHost + details.url) 
    .success(function (data) { 
     deferred.resolve(data); 
    }).error(function (msg) { 
     deferred.reject(msg); 
    }); 
return deferred.promise; 

ale możemy również skorzystać z tej metody również bez użycia $ q:

return $http.get(config.apiHost + details.url) 
    .success(function (data) { 
     return data; 
    }).error(function (msg) { 
     return msg; 
    }); 

i jak $ http sama zwraca obietnicę, mogę również użyć bardziej uproszczone podejście:

$http.get(config.apiHost + 'posts') 
     .success(function (data) { 
      console.log(data) 
     }).error(function (msg) { 
      console.log(msg); 
     }); 

Jaka jest różnica między tymi wszystkimi między $ q i $ http, ponieważ obie obietnice powracają, a obie są asynchroniczne? Czy kątowe zapewnia dodatkową funkcjonalność za pomocą $ q? Nie mogę znaleźć żadnej dobrej odpowiedzi.

+0

Możesz zwrócić obietnicę z innymi asynchronicznymi operacjami za pomocą $ q. $ http zwraca obietnicę z wywołań AJAX. – Hoyen

+0

inne operacje, takie jak? –

+0

Podobnie jak czytanie plików lub jeśli chcesz użyć $ timeout – Hoyen

Odpowiedz

2

$q służy głównie do kompatybilności z bibliotekami, które domyślnie nie obsługują obietnic i kiedy nie można polegać na natywnej implementacji Promise (na przykład - w starszych przeglądarkach takich jak IE9). Nie ma powodu (dla ciebie), aby użyć go w inny sposób. Przykładem byłoby, gdybyś chciał dokonać opartego na obietnicy $timeout. $http samo używa $q pod maską z tych dokładnych powodów.

W przeciwieństwie do tego, co inne (od skasowany) odpowiedzi sugerują, robisz nie$q trzeba użyć w celu „sklep” efektem obietnicy $http. Nie polecałabym składowania obietnicy w ogóle (ponieważ prowadzi to do kodu spaghetti), ale jeśli absolutnie musisz to zrobić, możesz po prostu zapisać wynikową obietnicę z $http; obietnice tylko raz wykonać raz.

Wszystkie funkcje przekazane do po rozstrzygnięciu/odrzuceniu obietnicy zostaną rozstrzygnięte przy następnym teście, bez powtórnego wywoływania pierwotnej akcji, która stworzyła obietnicę - IOW, wynik obietnicy jest pamiętany w ciągu ten obiekt.

Należy również pamiętać, że łańcuch obietnice, która jest odrobinę poza zakres tej odpowiedzi, ale w istocie oznacza, że ​​następujące fragmenty kodu są równoważne

function legacyGet() { 
    const deferred = $q.defer() 
    $http.get('http://www.google.com') 
    .then((response) => deferred.resolve(Object.assign(response, {foo: bar})) 
    .catch((error) => deferred.reject(error)) 
    return deferred.defer 
} 

function modernGet() { 
    return $http.get('http://www.google.com') 
    .then((response) => Object.assign(response, {foo: bar})) 
} 

Podsumowując: Twój tytuł jest źle. Nie preferujemy używania $ q, używamy go tylko oszczędnie. Wolisz używać obietnicy ES6, chyba że potrzebujesz obsługi przeglądarek, które jej nie mają: i nie możesz użyć polyfill.

7

używa $q, pierwszy przykład jest zbędny, tak jak i drugi. Trzeba tylko zwrócić obietnicę, że $http.get powraca:

return $http.get(config.apiHost + details.url); 

powyżej jest taki sam jak pierwszy kawałek kodu.

Ponadto return msg to nie to samo co deferred.reject(msg). Równowartość byłaby throw msg lub return $q.reject(msg)

Inną rzeczą jest, aby pamiętać, że success i error są niestandardowe, którego chcesz użyć then i catch.

+0

Nie powiedziałbym, że 'success' i' error' są "niestandardowe", po prostu przestarzałe: https://docs.angularjs.org/ api/ng/service/$ http – pulse0ne

+1

@ pulse0ne one * są * niestandardowe, jeśli mówisz o specyfikacji obietnicy A + –

+0

@ DanPantry ah, tak, błędnie myślałem, że odnosisz się do kątowej usługi $ http. W odniesieniu do specyfikacji, jest to niestandardowe i prawie na pewno, dlaczego ludzie kątowi go zahamowali. – pulse0ne

0

W wersji kątowej wszystkie usługi zwracają tylko obietnice, ale istnieją przypadki, w których chciałbyś utworzyć własny obiekt odroczony, używając $q.

Przypadek 1

Kiedy używasz biblioteki, która nie obsługuje obietnicę lub utworzyłeś własną funkcję i chcesz wrócić obietnicę.

Przypadek 2

Kiedy używasz żadnego konstruktu, który domyślnie zwraca obietnicę, ale chcesz powrócić oddzielny obietnicę w oparciu o niektóre na pewnym warunkiem.

Przykład W kątowych $http Zwraca obietnica tylko, ale teraz, jeśli chcesz, że jeśli odpowiedź tej obietnicy zawiera określoną wartość wtedy tylko chcesz powrócić rozwiązany innego niepowodzenie powrotny to trzeba tworzyć własne deffered object i trzeba rozwiązać lub go zawiodć na podstawie wartości zwróconej przez odpowiedź $http.

+0

Nie musisz tego robić. Obiecuje łańcuch. Możesz równie łatwo zrobić '$ http.get(). Then then (...)', a wartość zwrócona przez 'then' zostanie przekazana następnemu. Then w łańcuchu. Nie musisz używać do tego własnego odroczonego obiektu. –

+0

Mówię o odpowiedzi $ http.. like jeśli chcesz, jeśli odpowiedź zawiera pewną wartość niż tylko rozwiązać obietnicę lub po prostu odrzucić. –

+1

Ta odpowiedź jest niedokładna i opisuje powszechny odroczony wzorzec ochrony – charlietfl