2015-01-23 7 views
11

Uczę się RxJS czytając ten samouczek http://reactive-extensions.github.io/learnrx/.Co oznacza metoda `map` w RxJS?

Mam problem ze zrozumieniem metody map z Observable. Wersja Array jest bardzo prosta i prosta. Nie mam pojęcia, co dokładnie oznacza map w przypadku Observable (i dlaczego ma on alias o nazwie select?!).

Oto, co napisała mi dokumentacja. Może nie być pomocna dla większości początkujących ...

Projektuje każdy element obserwowalnej sekwencji w nowy formularz poprzez włączenie indeksu elementu. To jest alias dla wybranej metody.

Nie rozumiem map w kontekście event. Na przykład poniższy kod działa dokładnie tak, jak się spodziewałem. Myślałem o tym kodzie jako: "Posłuchaj click-event ze strumienia zdarzeń #btn".

var btnClicks, observable; 
 

 
btnClicks = Rx.Observable.fromEvent($('#btn'), "click"); 
 

 
observable = btnClicks.subscribe(function(e) { 
 
\t console.log(e); 
 
});

Ale co się dzieje, gdy staje się to ??

var btn2Clicks, btnClicks, observable; 
 

 
btnClicks = Rx.Observable.fromEvent($('#btn'), "click"); 
 

 
btn2Clicks = Rx.Observable.fromEvent($('#btn2'), "click"); 
 

 
observable = btnClicks.map(function(e) { 
 
    return btn2Clicks; 
 
}).subscribe(function(e) { 
 
    console.log(e); 
 
});

Co Myślałem jest użyć map przekształcić kolekcję Click zdarzenia do innej kolekcji event-kolekcji. filter jest łatwy do zrozumienia, tak jak słowo filter oznacza, weź wydarzenie tylko mnie interesuje i pomiń innych. Ale co powiesz na map w kontekście event? Jeśli oznacza to "przekształć kolekcję na inną", tak samo jak wersję tablicową, dlaczego wciąż strzela, gdy kliknięto #btn?

Chodzi mi o to, że zmapowałem to do innych kolekcji, teraz to już nie jest zbiór zdarzeń kliknięcia #btn, ale jest to nowa kolekcja czegoś ... Ale nadal strzela, gdy kliknęłam #btn, co nie ma sensu dla mnie .

Odpowiedz

18

map działa dokładnie tak samo dla Obserables, podobnie jak dla tablic. Używasz map, aby przekształcić kolekcję przedmiotów w kolekcję różnych przedmiotów. Pomaga, jeśli myślisz o Obserwowalnym jako kolekcji przedmiotów (podobnie jak tablica to także zbiór przedmiotów), przynajmniej z punktu widzenia obserwatora.

Na przykład, weźmy te 2 metody, które napisałeś do korzystania z niektórych tablicach:

function multiplyByTwo(collection) { 
    return collection.map(function (value) { 
     return value * 2; 
    }); 
} 

function removeZeroes(collection) { 
    return collection.filter(function (value) { 
     return value !== 0; 
    }); 
} 

var a = [1, 2, 3, 4, 0, 5]; 
var b = multiplyByTwo(a); // a new array [2, 4, 6, 8, 0, 10] 
var c = removeZeroes(b); // a new array [2, 4, 6, 8, 10] 

można użyć tych same funkcje dla zauważalny:

var a = Rx.Observable.of(1, 2, 3, 4, 0, 5); 
var b = multiplyByTwo(a); // a new observable [2, 4, 6, 8, 0, 10] 
var c = removeZeroes(b); // a new observable [2, 4, 6, 8, 10] 

Jest to możliwe, ponieważ Obserwacje RxJs implementują operatory macierzy, takie jak map i filter, aby mieć dokładnie taką samą semantykę jak w przypadku tablic. Jeśli wiesz, jak działają na tablicach, to wiesz, jak działają na obserwowalne.

Ta sztuczka jest wynikiem dual nature of observables and enumerables.

Podczas pracy z interaktywnym samouczkiem, który przeglądasz, faktycznie przeprowadzi Cię przez ten proces. Wierzę, że zaczyna się od pisania operatorów map dla tablic, a następnie w późniejszym samouczku zakrada zauważalne jako źródło.

P.S. Jest to alias dla select ze względu na swoją historię: Rozszerzenia reaktywne zostały po raz pierwszy zaimplementowane w .NET, a później przeniesione na inne języki. Rx.NET używa tych samych operatorów, które są używane przez LINQ .NET (ponieważ IObservable jest podwójnym z IEnumerable). Operator mapy LINQ znany jest jako Select (a jego operator filtru znany jest jako Where). Te nazwy pochodzą od źródła LINQ. Jednym z celów budowania LINQ było umożliwienie pisania zapytań do bazy danych w języku C#. W ten sposób przyjęli konwencje nazewnictwa SQL dla wielu operatorów (LINQ SELECT mapuje bezpośrednio do SQL SELECT, LINQ WHERE mapuje do SQL WHERE, itd.).

+0

Dzięki! Teraz wiem, dlaczego niektóre metody mają alias. Ale nadal nie mogę zrozumieć operacji 'map' w kontekście' zdarzenia'. Zmieniłem to pytanie, mam nadzieję, że możesz mi odpowiedzieć, co znaczy mapa, kiedy zajmujesz się wydarzeniami. – yaquawa

+0

@ Brandon, ale kiedy funkcja iteracji mapy? Kiedy mapujesz na tablicy, masz już wszystkie elementy w tablicy i iteruje log (n) razy przez każdy z elementów. Kiedy .map na Obserwowalne, czy obserwowalne już otrzymało wszystkie elementy (i iteruje przez każdą z nich) lub czy funkcje (w bloku mapy) działają na każdym elemencie (zdarzeniu), jaki przybył? Czy w przypadku Observables mapa działa jako iterator (tak jak w przypadku normalnych tablic), czy też jest bardziej dekoratorem dla każdego zdarzenia (elementu) do przejścia? –

+0

@BenjaminMcFerren Observables są oparte na push (źródła danych * push * dla subskrybentów (za pośrednictwem dowolnych operatorów takich jak 'map'), gdy dane stają się dostępne). Tak więc, w waszym żargonie, obserwowalne podmioty są jak dekoratorzy wydarzeń. – Brandon