2014-11-03 14 views
17

W JavaScript wzorzec obserwatora jest często używany. Jest z tym jedna trudna sprawa i to jest odniesienie, które utrzymuje obserwator. Wymagają sprzątania. Dla zwykłych aplikacji używam następujące reguły kciuka:Czy funkcjonalne programowanie reaktywne w JavaScript powoduje większe problemy z odniesieniami do słuchacza?

  • Jeżeli obiekt ma żywotność krótsza niż (lub równy) obserwator, mogę tylko zrobić subject.on('event', ...)
  • Jeżeli obiekt ma żywotność dłużej od obserwatora, muszę korzystać observer.listenTo(subject, 'event', ...)

W drugim przypadku, listenTo jest świadomy cyklu obserwatora, a zostanie ona automatycznie usunąć słuchaczy, gdy nadszedł czas dla obserwatora na śmierć.

W nowoczesnym stylu SPA (Single Page Application), w którym tylko części aplikacji są aktywne w dowolnym momencie, staje się to bardzo ważne. Jeśli połączysz to z gniazdami internetowymi, które są idealnym kandydatem do strumienia wydarzeń i najprawdopodobniej długo żyją, staje się to jeszcze ważniejsze.

Dzięki FRP, dysponując czymś takim jak strumień zdarzeń reprezentujący zmieniające się wartości w czasie, jestem (nie wiedząc o tym), tworząc wielu słuchaczy. Każdy filter, map i tworzy nowy strumień, który jest związany (prawdopodobnie za pomocą słuchacza) z poprzednim.

Moim zdaniem wydaje się dość trudne określenie, w jaki sposób i kiedy należy usunąć tych słuchaczy. Nie mogę sobie wyobrazić, że jestem pierwszą osobą, która pomyślała o tym problemie, ale nie mogłem znaleźć zbyt wielu informacji w Internecie.

Widziałem niektóre frameworki w innych językach używają słabych referencji. JavaScript nie ma pojęcia słabych referencji (nie ma tutaj zastosowania WeakMap). Nawet jeśli tak było, wydaje się, że jest to zły pomysł, ponieważ nie jest jasne, kiedy odbywa się zbieranie śmieci.

  • Jak to rozwiązano w obecnych ramach?
  • Czy ramy wiążą się z cyklem życia obiektów? Jeśli tak: w jaki sposób?
+1

Jeśli uważasz, że to pytanie powinno zostać zamknięte, dodaj komentarz. Może dodaj sugestię, aby pytanie było bardziej szczegółowe. A może wskaźnik do miejsca, w którym to pytanie lepiej pasuje. Jeśli nie jest jasne, zadaj pytania. Naprawdę chcę użyć FRP. – EECOLOR

+0

Przepraszam, musiałem głosować, aby zamknąć. To pytanie jest zbyt otwarte. –

+0

@JK. Czy masz jakieś sugestie dotyczące poprawy tego pytania? – EECOLOR

Odpowiedz

11

W RxJs każdy Observer będzie domyślnie mieć osobne słuchacza na oryginalnego źródła zdarzeń. Tak więc, jeśli masz

var s = $('#textInput').keyupAsObservable() 
s.subscribe(subscriber1); 
s.map(function() {}).subscribe(subscriber2); 

Będziesz mieć dwóch słuchaczy keyup. Możesz użyć .publish().refCount(), aby Observable utrzymywać pojedyncze połączenie z jego źródłem.

W Bacon.js, Observables zawsze utrzymują pojedyncze połączenie z ich źródłem.

W obu bibliotekach połączenie ze źródłem jest tworzone leniwie (po dodaniu Observer) i usuwane automatycznie po usunięciu (ostatniego) obserwatora. Dlatego nie musisz ręcznie zarządzać słuchaczami.

Jednak w przypadku, gdy subject ma dłuższą żywotność niż Observer, musisz upewnić się, że obserwator zatrzyma subskrypcję, gdy skończy się jej żywotność, lub wystąpi wyciek. Żadna z bibliotek nie ma "magicznego" sposobu zarządzania tym, ponieważ do biblioteki Twój Observer jest tylko funkcją.

Osobiście często stworzyć Observable nazywa death czy cokolwiek by zasygnalizować koniec z eksploatacji dla obserwatora, a następnie zamiast subskrybowania subject I subskrybować subject.takeUntil(death).

Jeśli chodzi o Elm, rozumiem, że skonfigurowałeś całą sieć wydarzeń na raz, więc nie ma możliwości wycieku; Observers nie można dodać na późniejszym etapie.

+0

Twoje zrozumienie Wiązu jest poprawne, więc możesz być bardziej asertywny w tym ostatnim stwierdzeniu. Język zezwala tylko na statyczne sieci zdarzeń (wykresy sygnałów, jak to się nazywa w wiązach), dlatego kod może być (i jest) skompilowany do JavaScriptu, który buduje pełną sieć w czasie inicjalizacji i nie musi zajmować się subskrypcją/rezygnacją z subskrypcji. – Apanatshka

+0

"Śmierć" to ciekawa koncepcja. Dobrze jest wiedzieć, że żadna ze wspomnianych struktur nie ma czegoś, co pomoże w cyklu życia. – EECOLOR

Powiązane problemy