Jaka jest różnica między Promise
i Observable
w Angular?
Przykład na każdym z nich byłby pomocny w zrozumieniu obu przypadków. W jakim scenariuszu możemy użyć każdego przypadku?
Jaka jest różnica między Promise
i Observable
w Angular?
Przykład na każdym z nich byłby pomocny w zrozumieniu obu przypadków. W jakim scenariuszu możemy użyć każdego przypadku?
Odpowiedzi:
Obietnica
Promise
Obsługuje pojedyncze zdarzenie , gdy an asynchroniczny finalizuje działania lub nie.
Uwaga: istnieją Promise
biblioteki obsługujące anulowanie, ale Promise
jak dotąd ES6 nie.
Zauważalny
Na Observable
jest jak Stream
(w wielu językach) i pozwala przekazać zero lub więcej zdarzeń, w których wywołanie zwrotne jest wywoływane dla każdego zdarzenia.
Często Observable
jest preferowany, Promise
ponieważ zapewnia funkcje Promise
i nie tylko. ZObservable
nie ma znaczenia, czy chcesz obsłużyć 0, 1, czy wiele zdarzeń. W każdym przypadku możesz użyć tego samego interfejsu API.
Observable
ma również tę zaletę, Promise
że można ją anulować . Jeśli wynik żądania HTTP do serwera lub innej kosztownej operacji asynchronicznej nie jest już potrzebny, oznacza Subscription
toObservable
pozwala anulować subskrypcję, a a Promise
ostatecznie wywoła sukces lub niepowodzenie wywołania zwrotnego, nawet jeśli nie potrzebujesz powiadomienia lub wynik, który zapewnia.
Obserwowalne zapewnia operatorom jak map
,forEach
, reduce
, ... podobne do tablicy
Istnieją również potężne operatory, takie jak retry()
lub replay()
..., które często są bardzo przydatne.
Promise
, wraz z async
/ await
sprawia, że twój kod znów jest płaski! W większości sytuacji oraz w projektach, które nie zajmują się naukami o rakietach, nie ma potrzeby pisania tych okropnych funkcji zagnieżdżonych za pomocą niepotrzebnie skomplikowanych łańcuchów metod. Możesz używać async
/ await
dzisiaj z transpilatorami, jak TypeScript
i pisać rzeczywisty, czytelny dla człowieka płaski kod bez żadnej płyty rxjs
głównej. Prawdopodobnie nadal będziesz potrzebować rxjs
czasami w wybranych sytuacjach, ponieważ naprawdę ma wiele rzeczy do zaoferowania.
Zarówno Promises
i Observables
dostarczyć nam abstrakcjami, które pomagają nam radzić sobie z asynchronicznym naturę naszych aplikacji. Różnicę między nimi wyraźnie wskazali @ Günter i @Relu.
Ponieważ fragment kodu jest wart tysiąca słów, przejrzyj poniższy przykład, aby je łatwiej zrozumieć.
Dzięki @Christoph Burgdorf za wspaniały artykuł
Angular używa Rx.js Observables zamiast obietnic do obsługi HTTP.
Załóżmy, że budujesz funkcję wyszukiwania, która powinna natychmiast wyświetlać wyniki podczas pisania. Brzmi znajomo, ale z tym zadaniem wiąże się wiele wyzwań.
HTTP
żądań. Zasadniczo chcemy go nacisnąć tylko wtedy, gdy użytkownik przestanie pisać zamiast z każdym naciśnięciem klawisza.Demo będzie się po prostu składało z dwóch plików: app.ts
i wikipedia-service.ts
. Jednak w prawdziwym świecie najprawdopodobniej podzielilibyśmy rzeczy dalej.
Poniżej znajduje się implementacja oparta na obietnicach , która nie obsługuje żadnego z opisanych przypadków krawędzi.
wikipedia-service.ts
import { Injectable } from '@angular/core';
import { URLSearchParams, Jsonp } from '@angular/http';
@Injectable()
export class WikipediaService {
constructor(private jsonp: Jsonp) {}
search (term: string) {
var search = new URLSearchParams()
search.set('action', 'opensearch');
search.set('search', term);
search.set('format', 'json');
return this.jsonp
.get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search })
.toPromise()
.then((response) => response.json()[1]);
}
}
Wstrzykiwamy Jsonp
usługę, aby zgłosić GET
żądanie przeciwko API Wikipedii przy użyciu określonego wyszukiwanego hasła. Zauważ, że my nazywamy toPromise
w celu uzyskania od Observable<Response>
Do Promise<Response>
. Ostatecznie otrzymamy Promise<Array<string>>
jako typ zwrotu naszej metody wyszukiwania.
app.ts
// check the plnkr for the full list of imports
import {...} from '...';
@Component({
selector: 'my-app',
template: `
<div>
<h2>Wikipedia Search</h2>
<input #term type="text" (keyup)="search(term.value)">
<ul>
<li *ngFor="let item of items">{{item}}</li>
</ul>
</div>
`
})
export class AppComponent {
items: Array<string>;
constructor(private wikipediaService: WikipediaService) {}
search(term) {
this.wikipediaService.search(term)
.then(items => this.items = items);
}
}
Tu też nie ma niespodzianki. Wstrzykiwamy naszą WikipediaService
i udostępniamy jej funkcjonalność za pomocą metody wyszukiwania do szablonu. Szablon po prostu wiąże się z keyup i wywołaniamisearch(term.value)
.
Rozpakowujemy wynik obietnicy, że metoda wyszukiwania WikipediaService zwraca i udostępniamy szablonowi jako prostą tablicę ciągów, abyśmy mogli mieć*ngFor
go przejrzeć i stworzyć dla nas listę.
Zobacz przykład implementacji opartej na obietnicach w firmie Plunker
Gdzie obserwatorzy naprawdę świecą
Zmieńmy nasz kod, aby nie wbijał punktu końcowego przy każdym naciśnięciu klawisza, ale zamiast tego wysyłał żądanie tylko wtedy, gdy użytkownik przestał pisać na 400 ms
Aby odsłonić takie super moce, najpierw musimy uzyskać taki, Observable<string>
który zawiera wyszukiwane hasło, które wpisuje użytkownik. Zamiast ręcznego wiązania się ze zdarzeniem keyup, możemy skorzystać z formControl
dyrektywy Angulara . Aby skorzystać z tej dyrektywy, musimy najpierw zaimportować ją ReactiveFormsModule
do naszego modułu aplikacji.
app.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JsonpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [BrowserModule, JsonpModule, ReactiveFormsModule]
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Po zaimportowaniu możemy użyć formControl z naszego szablonu i nadać mu nazwę „term”.
<input type="text" [formControl]="term"/>
W naszym komponencie tworzymy instancję FormControl
z@angular/form
i udostępniamy ją jako pole pod nazwą terminu na naszym komponencie.
Za kulisami termin automatycznie ujawnia Observable<string>
właściwość as valueChanges
, którą możemy subskrybować. Teraz, gdy mamy Observable<string>
, pokonanie danych wejściowych użytkownika jest tak proste, jak wywołanie debounceTime(400)
naszego Observable
. Zwróci to nową Observable<string>
, która wyemituje nową wartość tylko wtedy, gdy nie pojawią się nowe wartości przez 400 ms.
export class App {
items: Array<string>;
term = new FormControl();
constructor(private wikipediaService: WikipediaService) {
this.term.valueChanges
.debounceTime(400) // wait for 400ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));
}
}
Stratą zasobów byłoby wysłanie kolejnej prośby o wyszukiwany termin, dla którego nasza aplikacja już pokazuje wyniki. Wszystko, co musimy zrobić, aby osiągnąć pożądane zachowanie, to zadzwonić do distinctUntilChanged
operatora zaraz po tym, jak zadzwoniliśmydebounceTime(400)
Zobacz przykład Obserwowalnej implementacji na Plunkerze
Aby poradzić sobie z odpowiedziami na zamówienie, sprawdź pełny artykuł http://blog.thoughtram.io/angular/2016/01/06/taking-oughage-of-observables-in-angular2.html
O ile używam Http w Angular, zgadzam się, że w normalnych przypadkach użycia nie ma dużej różnicy przy użyciu Observable over Promise. Żadna z zalet nie ma tu tak naprawdę znaczenia w praktyce. Mam nadzieję, że zobaczę jakiś zaawansowany przypadek użycia w przyszłości :)
Ucz się więcej
Zarówno obietnice, jak i obserwowalne pomogą nam pracować z funkcjami asynchronicznymi w JavaScript. W wielu przypadkach są bardzo podobne, jednak nadal istnieją między nimi pewne różnice, obietnice są wartościami, które zostaną rozwiązane w asynchronous
sposób podobny do wywołań http . Z drugiej strony, obserwowalne zajmują się sekwencją zdarzeń asynchronicznych . Główne różnice między nimi wymieniono poniżej:
obietnica:
zauważalny:
Ponadto stworzyłem dla Ciebie obraz graficzny, aby wizualnie pokazać różnice:
Promise
jest niewłaściwym sposobem myślenia o tym, co obiecuje. Promise
„S odpowiedzialność tylko do sukcesu lub niepowodzenia rączki w kompatybilnym sposób asynchroniczny .. Jeśli chcesz, aby anulować żądanie http anulować żądanie, a nie obietnica, i sprawiają, że wynik odwołania albo spełniają lub odrzucić obietnicę. jsfiddle.net/greggman/ea0yhd4p
Obietnice
Obserwowalne
Jeden operator ponawiania mogą być wykorzystane, aby ponowić próbę jeśli zajdzie taka potrzeba, również jeśli musimy ponowić obserwowalny na podstawie pewnych warunkach retryWhen mogą być użyte.
Uwaga : Lista operatorów wraz z ich interaktywnymi diagramami jest dostępna tutaj na RxMarbles.com
W odpowiedziach brakuje jednej wady Obserwowalnych. Obietnice pozwalają korzystać z funkcji asynchronicznych / oczekujących ES7. Za ich pomocą możesz pisać kod asynchroniczny, tak jakby to było synchroniczne wywołanie funkcji, więc nie potrzebujesz już wywołań zwrotnych. Jedyną możliwością, aby Obserwatorzy to zrobili, jest przekonwertowanie ich na Obietnice. Ale po przekonwertowaniu ich na obietnice możesz ponownie mieć tylko jedną wartość zwracaną:
async function getData(){
const data = await observable.first().toPromise();
//do stuff with 'data' (no callback function needed)
}
Dalsza lektura: Jak mogę poczekać na Rx Observable?
Obietnice i Obserwowalne obsługują tylko wywołanie asynchroniczne.
Oto różnice między nimi:
Zauważalny
Obietnica
Emituje tylko jedną wartość na raz
Wywołuje usługi bez .then i .catch
Nie można anulować
Nie zapewnia żadnych operatorów
Mimo że odpowiedź jest późna, podsumowałem poniżej różnice,
Zauważalny:
function
co bierze an observer
i zwraca a function Observer: an object with next, error.
subscribe/unsubscribe
swojemu strumieniowi danych wysyłać następną wartość obserwatorowi, notify
obserwatorowi o tym errors
i informować go ostream completion
function to handle next value
, błędy i koniec strumienia (zdarzenia interfejsu użytkownika, odpowiedzi HTTP, dane z gniazdami sieciowymi).multiple values
czasemcancel-able/retry-able
i obsługuje operatorów takich jakmap,filter,reduce
itp.Observable.create()
- zwraca Obserwowalne, które może wywoływać metody na - Observer Observable.from()
- konwertuje tablicę lub iterowalne na - Observable Observable.fromEvent()
- konwertuje zdarzenie na Obserwowalne - Observable.fromPromise()
- konwertuje obietnicę na Obserwowalne - Observable.range()
- zwraca sekwencję liczb całkowitych w określonym zakresieObietnica :
Obietnica reprezentuje zadanie, które zakończy się w przyszłości;
Obietnice stają się resolved by a value
;
Obietnice są odrzucane przez wyjątki;
Nie cancellable
i to wracaa single value
Obietnica ujawnia funkcję (then)
- następnie zwraca nowy promise
;
-zezwolenia na attachment
to zostaną wykonane na podstawie
state
;
- handlers
mają guaranteed
zostać wykonane w order attached
;
Właśnie poradziłem sobie z problemem, w którym Obietnice były najlepszym rozwiązaniem, i dzielę się nim tutaj dla każdego, kto natknie się na to pytanie w przypadku, gdy jest ono przydatne (to była dokładnie odpowiedź, której szukałem wcześniej):
W projekcie Angular2 mam usługę, która przyjmuje niektóre parametry i zwraca listę wartości, aby wypełnić menu rozwijane w formularzu. Podczas inicjowania komponentu formularza muszę wywoływać tę samą usługę wiele razy z różnymi parametrami, aby zdefiniować wiele różnych menu rozwijanych, jednak jeśli po prostu ustawię w kolejce wszystkie zmienne w celu wywołania usługi, tylko ostatnia powiedzie się i błąd reszty na zewnątrz. Usługa pobierająca z bazy danych mogła obsłużyć tylko jedno żądanie na raz.
Jedynym sposobem na pomyślne wypełnienie wszystkich zmiennych menu rozwijanego było wywołanie usługi w sposób, który uniemożliwił przetworzenie nowego żądania aż do ostatniego żądania, a mechanizm Promise / .then rozwiązał problem.
fetchValueList(listCode): Promise<any> {
return this.dataSvc.getValueList(listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
.map(response => response.json())
.toPromise();
}
initializeDropDowns() {
this.fetchValueList('First-Val-List')
.then(data => {
this.firstValList = data;
return this.fetchValueList('Second-Val-List')
}).then(data => {
this.secondValList = data;
return this.fetchValueList('Third-Val-List')
}).then(data => {
this.thirdValList = data;
}) }
Zdefiniowałem funkcje w komponencie, a następnie wywołałem initializeDropDowns () w ngOnInit.
Funkcja fetchValueList zwraca obietnicę, więc pierwsze wywołanie przechodzi pierwszy listCode, a po rozwiązaniu obietnicy zwracana wartość znajduje się w zmiennej danych w bloku .then, w której możemy przypisać ją do zmiennej this.firstValList. Ponieważ funkcja zwróciła dane, wiemy, że usługa się zakończyła i można bezpiecznie wywoływać ponownie z drugim listCode, zwracana wartość znajduje się w zmiennej danych w następnym bloku .then i przypisujemy ją do zmiennej this.secondValList.
Możemy to połączyć tyle razy, ile jest to wymagane, aby zapełnić wszystkie zmienne, aw ostatnim bloku kodu po prostu pomijamy instrukcję return i blok się kończy.
Jest to bardzo szczególny przypadek użycia, w którym mamy jedną usługę, która musi być wywoływana wiele razy podczas inicjowania komponentu, i gdzie usługa musi zakończyć pobieranie i zwrócić wartość, zanim będzie mogła zostać ponownie wywołana, ale w tym przypadku metoda Obietnica / .tąd była idealna.
scan()
do zbudowania strumienia sekwencji obserwowalnych. Jednak twoje podejście może być bardziej wyraźne i łatwiejsze do zrozumienia.
Uważam, że wszystkie pozostałe odpowiedzi powinny wyjaśnić twoje wątpliwości. Niemniej jednak chciałem tylko dodać, że obserwowalne są oparte na programowaniu funkcjonalnym i uważam, że bardzo przydatne są funkcje, które się z tym wiążą, takie jak mapa, mapa, redukcja, zip. Spójność, którą osiąga sieć, szczególnie gdy zależy od żądań API, stanowi brutalną poprawę.
Zdecydowanie polecam tę dokumentację , ponieważ jest to oficjalna dokumentacja reactiveX i uważam, że jest najbardziej przejrzysta.
Jeśli chcesz zagłębić się w obserwowalne, proponuję ten 3-częściowy post: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
Chociaż jest przeznaczony dla RxJava, koncepcje są takie same i bardzo dobrze wyjaśnione. W dokumentacji reactiveX masz odpowiedniki dla każdej funkcji. Musisz poszukać RxJS.
Zawsze możesz użyć obserwowalnego do radzenia sobie z zachowaniem asynchronicznym, ponieważ obserwowalny ma całą funkcjonalność, którą oferuje obietnica (+ dodatkowe). Czasami jednak ta dodatkowa funkcjonalność oferowana przez Observables nie jest potrzebna. W takim przypadku dodatkowym kosztem byłoby zaimportowanie biblioteki, aby mogła z nich korzystać.
Użyj obietnic, gdy masz jedną operację asynchroniczną, której wynik chcesz przetworzyć. Na przykład:
var promise = new Promise((resolve, reject) => {
// do something once, possibly async
// code inside the Promise constructor callback is getting executed synchronously
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
//after the promise is resolved or rejected we can call .then or .catch method on it
promise.then((val) => console.log(val)) // logs the resolve argument
.catch((val) => console.log(val)); // logs the reject argument
Tak więc obietnica wykonuje kod, który rozwiązuje lub odrzuca. W przypadku wywołania rozwiązania lub odrzucenia obietnica przechodzi ze stanu oczekującego do stanu rozstrzygniętego lub odrzuconego . Po rozwiązaniu stanu obietnicy then()
wywoływana jest metoda. Kiedy stan obietnicy zostanie odrzucony,catch()
wywoływana jest metoda
Użyj Obserwowalnych, gdy z upływem czasu istnieje strumień (danych), z którym musisz sobie poradzić. Strumień jest sekwencją elementów danych, które są udostępniane w miarę upływu czasu . Przykłady strumieni to:
W Observable sam określa się, kiedy nastąpiło następne zdarzenie , kiedy wystąpił błąd lub kiedy Observable został zakończony . Następnie możemy zasubskrybować ten obserwowalny, który go aktywuje, aw tym abonamencie możemy przekazać 3 oddzwaniania (nie zawsze trzeba przekazywać wszystkie). Jedno wywołanie zwrotne należy wykonać w celu pomyślnego zakończenia, jedno wywołanie zwrotne w przypadku błędu i jedno wywołanie zwrotne w celu zakończenia. Na przykład:
const observable = Rx.Observable.create(observer => {
// create a single value and complete
observer.onNext(1);
observer.onCompleted();
});
source.subscribe(
x => console.log('onNext: %s', x), // success callback
e => console.log('onError: %s', e), // error callback
() => console.log('onCompleted') // completion callback
);
// first we log: onNext: 1
// then we log: onCompleted
Podczas tworzenia obserwowalnego wymaga funkcji zwrotnej, która dostarcza obserwatora jako argumentu. Na tej obserwatora, to wtedy można nazwać onNext
, onCompleted
, onError
. Następnie, gdy Obserwowalny jest zasubskrybowany, wywoła odpowiednie wywołania zwrotne przekazane do subskrypcji.
Obietnica - Podaj jedną przyszłą wartość. Nie leniwy . Nie można anulować. Odrzuci lub rozwiąże.
Obserwowalny - zapewnia wiele przyszłych wartości. Leniwy . Możliwość anulowania. Zapewnia inne metody mapy na żywo, filtrowania, zmniejszania.
const promise = new Promise(resolve => {
setTimeout(() => {
resolve("Hello from a Promise!");
}, 2000);
});
promise.then(value => console.log(value));
Obserwowalny przykład teraz. Tutaj również przekazujemy funkcję obserwowalnym, obserwatorowi do obsługi zadania asynchronicznego. W przeciwieństwie do rozwiązania zawartego w obietnicy ma on następującą metodę i subskrybuje zamiast niej.
Więc oba obsługują zadania asynchroniczne. Zobaczmy teraz różnicę.
const observable = new Observable(observer => {
setTimeout(() => {
observer.next('Hello from a Observable!');
}, 2000);
});
observable.subscribe(value => console.log(value));
Obietnica
Zauważalny
Zarówno obietnice, jak i obserwowalne pomagają nam radzić sobie z operacjami asynchronicznymi. Mogą wywoływać określone połączenia zwrotne, gdy wykonywane są te operacje asynchroniczne.
Angular używa Observables, który pochodzi z RxJS zamiast obietnic dotyczących obsługi HTTP
Below are some important differences in promises & Observables.
Obietnica emituje pojedyncze zdarzenie, gdy działanie asynchroniczne kończy się lub kończy się niepowodzeniem.
Obserwowalny jest jak Strumień (w wielu językach) i pozwala przekazać co najmniej zero lub więcej zdarzeń, w których wymagane jest wywołanie zwrotne dla każdego zdarzenia.
Często obserwowalny jest lepszy od Promise, ponieważ daje najważniejsze obietnice i więcej. W Observable nie ma znaczenia, czy chcesz obsłużyć 0, 1, czy różne zdarzenia. Możesz użyć podobnego API dla każdego przypadku.
Obietnica: obietnica emituje jedną wartość
Na przykład:
const numberPromise = new Promise((resolve) => {
resolve(5);
resolve(10);
});
numberPromise.then(value => console.log(value));
// still prints only 5
Zauważalny: emituje wiele wartości w pewnym okresie czasu
Na przykład:
const numberObservable = new Observable((observer) => {
observer.next(5);
observer.next(10);
});
numberObservable.subscribe(value => console.log(value));
// prints 5 and 10
możemy myśleć o obserwowalnym strumieniu, który emituje wiele wartości w danym okresie czasu i dla każdego emitowanego elementu wywoływana jest ta sama funkcja zwrotna, więc za pomocą obserwowalnego możemy używać tego samego interfejsu API do obsługi danych asynchronicznych. czy dane te są przesyłane jako pojedyncza wartość czy wiele wartości w pewnym przedziale czasu.
Obietnica:
Zauważalny:
Promise emituje jedną wartość, a Observable emituje wiele wartości. Tak więc, podczas obsługi żądania HTTP, Promise może zarządzać pojedynczą odpowiedzią na to samo żądanie, ale co zrobić, jeśli istnieje wiele odpowiedzi na to samo żądanie, wówczas musimy użyć Observable. Tak, Observable może obsłużyć wiele odpowiedzi dla tego samego żądania.
Obietnica
const promise = new Promise((data) =>
{ data(1);
data(2);
data(3); })
.then(element => console.log(‘Promise ‘ + element));
Wynik
Promise 1
Zauważalny
const observable = new Observable((data) => {
data.next(1);
data.next(2);
data.next(3);
}).subscribe(element => console.log('Observable ' + element));
Wynik
Observable 1
Observable 2
Observable 3
Poniżej kilka ważnych różnic w obietnicach i obserwowalnościach.
Obietnica
Zauważalny
Aby lepiej zrozumieć, odwiedź https://stackblitz.com/edit/observable-vs-promises
Widzę wielu ludzi używających argumentu, że „Obserowalne” można „anulować”, ale ustawienie „Obietnicy” jest dość trywialne.
function cancellablePromise(body) {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res; reject = rej;
body(resolve, reject)
})
promise.resolve = resolve;
promise.reject = reject;
return promise
}
// Example 1: Reject a promise prematurely
const p1 = cancellablePromise((resolve, reject) => {
setTimeout(() => resolve('10', 100))
})
p1.then(value => alert(value)).catch(err => console.error(err))
p1.reject(new Error('denied')) // expect an error in the console
// Example: Resolve a promise prematurely
const p2 = cancellablePromise((resolve, reject) => {
setTimeout(() => resolve('blop'), 100)
})
p2.then(value => alert(value)).catch(err => console.error(err))
p2.resolve(200) // expect an alert with 200
Krótka odpowiedź :
Obserwowalne jest lepsze , ma wszystkie funkcje Obietnic plus dodatkowe funkcje.
Długa odpowiedź:
Obietnice:
Zauważalny:
Chociaż ogólnie przyjęta odpowiedź jest dobra, nie sądzę, aby podkreślała, że w przypadku Komponentów Angularnych prawie zawsze chcesz użyć Obserwowalnego, ponieważ obsługuje anulowanie. Obietnic nie można anulować i zostaną one rozwiązane, nawet jeśli element zostanie zniszczony. Angular zwykle wybacza, dopóki tak nie jest.
Na przykład każde ręczne wykrycie zmiany w zniszczonym komponencie spowoduje wyjątek:
ngOnInit() {
// promise api
this.service.getData().then(d => {
this.data = d;
this.changeDetectorRef.detectChanges();
});
// observable api
this.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {
this.data = d;
this.changeDetectorRef.detectChanges();
});
}
Jeśli twój komponent zostanie zniszczony przed rozpatrzeniem obietnicy, otrzymasz attempt to use destroyed view
błąd, gdy obietnica zostanie rozwiązana.
Alternatywnie, jeśli używasz obserwowalnych z takeUntil wzorcem , to natychmiast po zniszczeniu komponentu subskrypcja zostanie anulowana.
To trochę wymyślony przykład, ale wykonanie kodu dla zniszczonego komponentu prawdopodobnie doprowadzi do błędów. Chyba że faktycznie chcesz to zrobić z jakiegoś powodu: str
Coś, na co wpadłem, nie było oczywiste po pierwszym czytaniu samouczka i dokumentów, było pomysłem multiemisji.
Upewnij się, że wiesz, że domyślnie wiele subskrypcji wywoła wiele wykonań w polu Observable. Wiele subskrypcji dla pojedynczego połączenia HTTP Observable wyzwoli wiele identycznych połączeń HTTP, chyba że Ty.share()
(umożliwisz multiemisję).
Obietnica zmusza cię do radzenia sobie z jedną rzeczą na raz, rozpakowywania danych, obsługi wyjątków, ma obsługę języków dla fajnych rzeczy, takich jak async / czekaj, a poza tym jest całkiem prosta.
Obserwowalny ma wiele dzwonków i gwizdków, ale musisz zrozumieć moc, z którą pracujesz, w przeciwnym razie może zostać niewłaściwie wykorzystany.
Obietnica:
Asynchroniczny moduł obsługi zdarzeń - obiekt Promise reprezentuje ostateczne zakończenie (lub niepowodzenie) operacji asynchronicznej i jej wynikową wartość.
Składnia: nowa obietnica (executor);
Na przykład:
var promise_eg = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
promise_eg.then(function(value) {
console.log(value);
// expected output: "foo"
});
console.log(promise_eg);
O Promise: ma jeden potok, więc zwróci wartości tylko raz, gdy zostanie wywołany. jego jednokierunkowy moduł obsługi, więc po wywołaniu możesz nie móc anulować. przydatna składnia, w którą możesz się bawić, kiedy (), a potem ()
Obserwowalne:
Obserwowalne to leniwe zbiory wielu wartości w czasie. to naprawdę świetne podejście do operacji asynchronicznych. można to zrobić za pomocą rxjs, który ma obsługę wielu platform, może używać z angular / reagować itp.
działa jak liniowiec. może być wiele potoków. więc po zdefiniowaniu możesz zapisać się, aby uzyskać wyniki zwrotów w wielu miejscach.
Składnia: import * as Rx from "@reactivex/rxjs";
do init:
Rx.Observable.fromEvent(button, "click"),
Rx.Subject()
itp
subskrybować: RxLogger.getInstance();
Na przykład:
import { range } from 'rxjs';
import { map, filter } from 'rxjs/operators';
range(1, 200).pipe(
filter(x => x % 2 === 1),
map(x => x + x)
).subscribe(x => console.log(x));
Ponieważ obsługuje wiele potoków, możesz subskrybować wyniki w innej lokalizacji, ma wiele możliwości niż obiecuje.
Zastosowanie:
ma więcej możliwościmap, filter, pipe, map, concatMap etc
Obserwowalne są często porównywane do obietnic. Oto kilka kluczowych różnic:
Obserwowalne są deklaratywne; obliczenia zaczynają się dopiero po subskrypcji. Obietnice wykonują się natychmiast po stworzeniu. To sprawia, że obserwowalne są przydatne do definiowania przepisów, które można uruchamiać, gdy tylko potrzebujesz wyniku.
Obserwowalne dają wiele wartości. Obietnice zapewniają jedno. To sprawia, że obserwowalne są przydatne do uzyskiwania wielu wartości w czasie.
Obserwowalne rozróżniają łańcuchy i subskrypcje. Obietnice mają tylko klauzule .then (). To sprawia, że obserwowalne są przydatne do tworzenia złożonych receptur transformacji do wykorzystania przez inne części systemu, bez konieczności wykonywania pracy.
Observables subscribe () odpowiada za obsługę błędów. Obietnice popychają błędy do obietnic dziecka. To sprawia, że obserwowalne są przydatne do scentralizowanej i przewidywalnej obsługi błędów.
To najprostsza różnica, jaką można znaleźć w dokumentach ANGULAR.IO. reszta odpowiedzi jest udzielana przez większość jest poprawna na swoim miejscu
Obietnice skupiają się tylko na pojedynczych wartościach lub rozwiązaniach, obserwowalne są strumieniem danych.
Obserwowalne można anulować, ale obietnic nie można anulować.
Najmniej znany, przynajmniej dla mnie, to
Obserwowalne i obietnice pomagają nam pracować z asynchronicznymi funkcjami JavaScript / maszynopisu. W wielu przypadkach są bardzo podobne, jednak nadal istnieją między nimi pewne różnice.
Istnieje już wiele odpowiedzi na ten temat, więc nie dodam zbędnych.
Ale dla kogoś, kto właśnie zaczął uczyć się Observable / Angular i zastanawia się, którego użyć, porównać z Obietnicą , poleciłbym zachować wszystko Observable i przekonwertować wszystkie istniejące Obietnice w twoim projekcie na Observable.
Po prostu dlatego, że sam framework Angular i jego społeczność używają Observable. Byłoby więc korzystne, gdybyś zintegrował usługi frameworku lub moduły stron trzecich i połączył wszystko razem.
Chociaż doceniam wszystkie opinie, ale wciąż nalegam na moją opinię powyżej, chyba że ktoś umieści odpowiedni komentarz, aby wymienić kilka scenariuszy, które mogą być nadal przydatne w twoim projekcie Angulara, aby użyć Obietnic zamiast Obserowaczy.
Oczywiście, żadna opinia nie jest w 100% poprawna we wszystkich przypadkach, ale przynajmniej uważam, że 98% czasu na zwykłe projekty komercyjne realizowane w Angular, Observable jest właściwą drogą.
Nawet jeśli nie spodoba ci się to na początku Twojego prostego projektu hobby, wkrótce zdasz sobie sprawę, że prawie wszystkie komponenty, z którymi współpracujesz w Angular, a większość przyjaznych dla środowiska frameworków Angular używa Observables, kończyło się to ciągłym przekształcaniem Obietnicy w Observable w celu komunikowania się z nimi.
Składniki te obejmują między innymi: HttpClient, konstruktor formularzy, moduły / okna dialogowe materiałów Angular, sklep / efekty Ngrx i bootstrap ngx.
W rzeczywistości jedyną obietnicą z ekosystemu Angular, z którą korzystałem w ciągu ostatnich 2 lat, jest APP_INITIALIZER
.