Zastanawiam się, jaki jest pożytek z asObservable
:
Zgodnie z dokumentami:
Obserwowalna sekwencja, która ukrywa tożsamość sekwencji źródłowej.
Ale dlaczego miałbyś ukrywać sekwencję?
Zastanawiam się, jaki jest pożytek z asObservable
:
Zgodnie z dokumentami:
Obserwowalna sekwencja, która ukrywa tożsamość sekwencji źródłowej.
Ale dlaczego miałbyś ukrywać sekwencję?
Odpowiedzi:
Ma to na celu zapobieżenie wyciekowi „strony obserwatora” podmiotu z API. Zasadniczo, aby zapobiec nieszczelnej abstrakcji, gdy nie chcesz, aby ludzie byli w stanie „przejść” do wynikowego obserwowalnego.
(UWAGA: To naprawdę nie jest sposób, w jaki powinieneś przekształcić źródło danych w Observable, zamiast tego powinieneś użyć new Observable
konstruktora, patrz poniżej).
const myAPI = {
getData: () => {
const subject = new Subject();
const source = new SomeWeirdDataSource();
source.onMessage = (data) => subject.next({ type: 'message', data });
source.onOtherMessage = (data) => subject.next({ type: 'othermessage', data });
return subject.asObservable();
}
};
Teraz, gdy ktoś uzyska obserwowalny wynik, myAPI.getData()
nie może next
wartościować wyniku:
const result = myAPI.getData();
result.next('LOL hax!'); // throws an error because `next` doesn't exist
new Observable()
Jednak zwykle powinieneś używaćW powyższym przykładzie prawdopodobnie tworzymy coś, czego nie chcieliśmy. Po pierwsze, getData()
nie jest leniwy jak większość obserwabli, natychmiast utworzy bazowe źródło danych SomeWeirdDataSource
(i prawdopodobnie niektóre efekty uboczne). Oznacza to również, że jeśli ty retry
lub repeat
wynikowy obserwowalny, nie będzie działać tak, jak myślisz, że będzie.
Lepiej jest zawrzeć tworzenie źródła danych w obserwowalnym, jak poniżej:
const myAPI = {
getData: () => return new Observable(subscriber => {
const source = new SomeWeirdDataSource();
source.onMessage = (data) => subscriber.next({ type: 'message', data });
source.onOtherMessage = (data) => subscriber.next({ type: 'othermessage', data });
return () => {
// Even better, now we can tear down the data source for cancellation!
source.destroy();
};
});
}
Z powyższym kodem, każde zachowanie, w tym uczynienie go „nie leniwym”, można skomponować na wierzchu obserwowalnego przy użyciu istniejących operatorów RxJS.
result.subscribe(value => doSomething(value))
return subject.asObservable();
będzie to nowe obserwowalne. Będziesz mieć jedną zmienną składową Subject, a onMessage / onOtherMessage zostanie zadeklarowany w warunku lub podczas inicjalizacji (nie przy każdym wywołaniu). Użyłem tego podejścia, pipe( filter() )
opierając się na parametrze dostarczonym do getData()
funkcji. The
subject
ma być subscriber
?
subject.next
linie powinny być subscriber
. Ponadto „jeśli spróbujesz ponownie lub powtórzysz wynikową obserwację, nie będzie działać tak, jak myślisz”. Czy mógłbyś to sprecyzować? Czy masz po prostu na myśli, że new SomeWeirdDataSource()
będzie się to działo za każdym razem, gdy getData
zostanie wywołany, i że przez zawijanie go new Observable
sprawisz, że instancja będzie czekać na subskrypcję. Chyba nie widzę, kiedy sprawdzisz getData
bez znaku, .subscribe
więc brakuje mi wartości. Wreszcie, co według Ciebie stanie się, aby „zniszczyć źródło danych”? Dzięki.
A Subject
może działać zarówno jako plik, jak observer
i jako observable
.
Na Obervable
ma 2 metody.
Kiedykolwiek subskrybować do observable
, masz observer
który ma kolejną , błąd i kompletne metody.
Musisz ukryć sekwencję, ponieważ nie chcesz, aby źródło strumienia było publicznie dostępne w każdym komponencie. Możesz się odwołać@BenLesh
przykładu.
PS: Kiedy pierwszy raz przeszedłem przez Reactive Javascript, nie byłem w stanie tego zrozumieć asObservable
. Ponieważ musiałem się upewnić, że dobrze rozumiem podstawy, a następnie zacząłem asObservable
. :)