Więc teraz dzięki swift ludzie ReactiveCocoa przepisali go w wersji 3.0 dla swift
Pojawiło się też inne przedsięwzięcie o nazwie RxSwift .
Zastanawiam się, czy ludzie mogliby dodać informacje o różnicach w projekcie / api / filozofii obu ram (proszę, w duchu SO, trzymaj się rzeczy, które są prawdziwe, a nie opinii o tym, co jest najlepsze)
[Uwaga dla modów StackOverflow: To pytanie NIE ma ostatecznych odpowiedzi, odpowiedzią są różnice między tymi dwoma frameworkami. Myślę, że jest to również temat na SO]
Na początek moje pierwsze wrażenie z przeczytania ich ReadMe to:
- Jako osoba znająca „prawdziwy” C # Rx firmy Microsoft, RxSwift wygląda o wiele bardziej rozpoznawalnie.
- Wygląda na to, że ReactiveCococa weszła teraz w swoją własną przestrzeń, wprowadzając nowe abstrakcje, takie jak Sygnały kontra SignalProducers i Lifting. Z jednej strony wydaje się to wyjaśniać niektóre sytuacje (co to jest sygnał Hot vs. Cold), ale z drugiej strony wydaje się, że zwiększa to złożoność frameworka
swift
reactive-programming
rx-swift
reactive-cocoa-3
Orion Edwards
źródło
źródło
Odpowiedzi:
To jest bardzo dobre pytanie. Porównywanie dwóch światów jest bardzo trudne. Rx to port Reaktywnych rozszerzeń w innych językach, takich jak C #, Java lub JS.
Reactive Cocoa został zainspirowany przez funkcjonalne programowanie reaktywne , ale w ostatnich miesiącach został również wskazany jako zainspirowany również przez Reactive Extensions . Rezultatem jest struktura, która dzieli niektóre rzeczy z Rx, ale ma nazwy pochodzące z FRP.
Pierwszą rzeczą do powiedzenia jest to, że ani RAC, ani RxSwift nie są implementacjami Funkcjonalnego Reaktywnego Programowania , zgodnie z definicją Conala . Od tego momentu wszystko można sprowadzić do tego, jak każda struktura obsługuje efekty uboczne i kilka innych składników.
Porozmawiajmy o społeczności i rzeczach związanych z meta-technologią :
Teraz czas na rzeczy techniczne.
Produkcja / obserwacja podmiotów
RAC 3.0 ma 2 główne jednostki,
Signal
aSignalProducer
pierwsza publikuje zdarzenia bez względu na to, czy subskrybent jest przyłączony czy nie, a druga wymagastart
wygenerowania sygnałów / zdarzeń. Ten projekt został stworzony, aby oddzielić nużącą koncepcję obserwowalnych na gorąco i na zimno, co było źródłem zamieszania dla wielu programistów. Dlatego różnice można ograniczyć do sposobu radzenia sobie z efektami ubocznymi .W RxSwift
Signal
iSignalProducer
przekłada się naObservable
, może to zabrzmieć myląco, ale te dwie istoty są w rzeczywistości takie same w świecie Rx. Projekt zObservable
R w RxSwift musi zostać utworzony, biorąc pod uwagę, czy są gorące czy zimne, może to zabrzmieć jako niepotrzebna złożoność, ale gdy zrozumiesz, jak działają (i ponownie gorący / zimny / ciepły dotyczy tylko skutków ubocznych podczas subskrybowania / obserwowania ) można je oswoić.W obu światach koncepcja subskrypcji jest w zasadzie taka sama, istnieje jedna niewielka różnica, którą wprowadził RAC, i jest to
interruption
wydarzenie, w którym aSignal
jest usuwane przed wysłaniem zdarzenia zakończenia. Podsumowując, oba mają następujące rodzaje zdarzeń:Next
, aby obliczyć nową otrzymaną wartośćError
, aby obliczyć błąd i ukończyć strumień, anulując subskrypcję wszystkich obserwatorówComplete
, aby oznaczyć strumień jako zakończony, anulując subskrypcję wszystkich obserwatorówRAC dodatkowo ma
interrupted
to, że jest wysyłane, gdy aSignal
jest usuwane przed ukończeniem poprawnie lub z błędem.Pisanie ręczne
W RAC
Signal
/SignalProducer
są jednostkami tylko do odczytu, nie można nimi zarządzać z zewnątrz, to samo dotyczyObservable
RxSwift. Aby zmienić aSignal
/SignalProducer
w jednostkę, która może zapisywać, musisz użyćpipe()
funkcji, aby zwrócić ręcznie sterowany element. W przestrzeni Rx jest to inny typ o nazwieSubject
.Jeśli koncepcja odczytu / zapisu wydaje się nieznana, można dokonać przyjemnej analogii z
Future
/Promise
.Future
Jest tylko do odczytu zastępczy, jakSignal
/SignalProducer
aObservable
, z drugiej strony,Promise
mogą być wypełniane ręcznie, jak napipe()
iSubject
.Harmonogramy
Ta jednostka jest bardzo podobna w obu światach, w tych samych koncepcjach, ale RAC jest tylko szeregowy, zamiast tego RxSwift oferuje również współbieżne harmonogramy.
Kompozycja
Kompozycja jest kluczową cechą programowania reaktywnego. Komponowanie strumieni jest istotą obu struktur, w RxSwift są one również nazywane sekwencjami .
Wszystkie podmioty RxSwift obserwowalne są typu
ObservableType
, więc komponować wystąpieńSubject
iObservable
z tych samych operatorów, bez żadnych dodatkowych obaw.Na przestrzeni RAC,
Signal
iSignalProducer
są 2 różne podmioty i musimylift
naSignalProducer
, aby móc komponować co jest produkowane z wystąpieńSignal
. Oba byty mają swoich operatorów, więc kiedy musisz mieszać różne rzeczy, musisz upewnić się, że określony operator jest dostępny, z drugiej strony zapominasz o obserwowalnych temperaturach na gorąco i na zimno.O tej części Colin Eberhardt ładnie to podsumował:
Dodatkowy
RAC ma również koncepcję,
Action
aProperty
ten pierwszy jest typem do obliczania skutków ubocznych, głównie związanych z interakcją użytkownika, ten drugi jest interesujący, gdy obserwuje się wartość w celu wykonania zadania, gdy wartość się zmieniła. W RxSwiftAction
ponownie przekłada się naObservable
, jest to dobrze pokazaneRxCocoa
, integracja prymitywów Rx na iOS i Mac. RACProperty
można przetłumaczyć naVariable
(lubBehaviourSubject
) w RxSwift.Ważne jest, aby zrozumieć, że
Property
/Variable
to sposób, w jaki musimy połączyć imperatywny świat z deklaratywnym charakterem Reactive Programming, więc czasami jest to podstawowy element w kontaktach z bibliotekami stron trzecich lub podstawowymi funkcjami przestrzeni iOS / Mac.Wniosek
RAC i RxSwift to 2 kompletnie różne bestie, ta pierwsza ma długą historię w przestrzeni kakaowej i wielu współpracowników, ta druga jest dość młoda, ale opiera się na koncepcjach, które okazały się skuteczne w innych językach, takich jak Java, JS lub .NETTO. Decyzja, która opcja jest lepsza, zależy od preferencji. RAC stwierdza, że oddzielenie obserwowalnego gorącego / zimnego było konieczne i że jest to podstawowa cecha frameworka, RxSwift twierdzi, że ich unifikacja jest lepsza niż separacja, znowu chodzi tylko o to, jak efekty uboczne są kontrolowane / wykonywane.
Wydaje się, że RAC 3.0 wprowadził nieoczekiwaną złożoność nad głównym celem oddzielenia obserwowalnych wartości od gorących / zimnych, jak koncepcja przerwania, rozdzielenie operatorów między 2 byty i wprowadzenie pewnych zachowań koniecznych, takich jak
start
rozpoczęcie produkcji sygnałów. Dla niektórych osób te rzeczy mogą być miłe, a nawet zabójcze, dla innych mogą być niepotrzebne lub nawet niebezpieczne. Kolejną rzeczą do zapamiętania jest to, że RAC stara się jak najlepiej nadążać za konwencjami Cocoa, więc jeśli jesteś doświadczonym twórcą Cocoa, powinieneś czuć się bardziej komfortowo z nim pracować, niż z RxSwift.Z drugiej strony RxSwift żyje ze wszystkimi wadami, takimi jak obserwowalne ciepło / zimno, ale także z dobrymi cechami Reactive Extensions. Przejście z RxJS, RxJava lub Rx.Net do RxSwift jest prostą rzeczą, wszystkie koncepcje są takie same, więc to sprawia, że znalezienie materiału jest dość interesujące, być może ten sam problem, przed którym teraz stoisz, został rozwiązany przez kogoś w RxJava i rozwiązanie można ponownie zastosować, biorąc pod uwagę platformę.
To, który należy wybrać, jest zdecydowanie kwestią preferencji, z obiektywnego punktu widzenia nie można stwierdzić, który jest lepszy. Jedynym sposobem jest zwolnienie Xcode i wypróbowanie obu z nich i wybranie tego, z którym wygodniej jest pracować. Są to 2 implementacje podobnych koncepcji, starające się osiągnąć ten sam cel: uproszczenie tworzenia oprogramowania.
źródło
NoError
) w samych typach strumienia:Signal<T, E: ErrorType>
kontraObservable<T>
. To, podobnie jak separacja na gorąco i na zimno, zapewnia zwiększoną ilość informacji w czasie kompilacji, których po prostu nie maszRxSwift
.