Alors maintenant avec swift, les gens de ReactiveCocoa l' ont réécrit dans la version 3.0 pour swift
En outre, il y a eu un autre projet lancé sous le nom de RxSwift .
Je me demande si les gens pourraient ajouter des informations sur les différences de conception / API / philosophie des deux cadres (veuillez, dans l'esprit de SO, vous en tenir aux choses qui sont vraies, plutôt qu'aux opinions sur ce qui est "le meilleur")
[Remarque pour les mods StackOverflow: cette question a des réponses définitives, la réponse est la différence entre les deux frameworks. Je pense que c'est aussi un sujet très important pour SO]
Pour commencer, mon impression initiale de la lecture de leurs Lisez-moi est la suivante:
- En tant que quelqu'un qui connaît le "vrai" C # Rx de Microsoft, RxSwift semble beaucoup plus reconnaissable.
- ReactiveCococa semble être parti dans son propre espace maintenant, introduisant de nouvelles abstractions telles que Signals vs SignalProducers et Lifting. D'une part, cela semble clarifier certaines situations (ce qui est un signal Hot vs Cold) mais d'autre part, cela semble augmenter la complexité du cadre un LOT
swift
reactive-programming
rx-swift
reactive-cocoa-3
Orion Edwards
la source
la source
Réponses:
C'est une très bonne question. Comparer les deux mondes est très difficile. Rx est un portage de ce que sont les extensions réactives dans d'autres langages comme C #, Java ou JS.
Reactive Cocoa a été inspiré par la programmation fonctionnelle réactive , mais au cours des derniers mois, il a également été souligné inspiré par les extensions réactives . Le résultat est un cadre qui partage certaines choses avec Rx, mais qui a des noms d'origine dans FRP.
La première chose à dire est que ni RAC ni RxSwift ne sont des implémentations de programmation réactive fonctionnelle , selon la définition de Conal de concept. À partir de là, tout peut être réduit à la façon dont chaque framework gère les effets secondaires et quelques autres composants.
Parlons de la communauté et de la méta-technologie :
Il est maintenant temps pour la technologie.
Entités productrices / observatrices
RAC 3.0 a 2 entités principales,
Signal
etSignalProducer
, la première publie des événements indépendamment du fait qu'un abonné soit attaché ou non, la seconde nécessite une productionstart
effective de signaux / événements. Cette conception a été créée pour séparer le concept fastidieux des observables chauds et froids, qui a été source de confusion pour de nombreux développeurs. C'est pourquoi les différences peuvent être réduites à la façon dont elles gèrent les effets secondaires .Dans RxSwift,
Signal
et cela seSignalProducer
traduit parObservable
, cela peut sembler déroutant, mais ces 2 entités sont en fait la même chose dans le monde Rx. Un design avecObservable
s dans RxSwift doit être créé en considérant s'ils sont chauds ou froids, cela peut sembler une complexité inutile, mais une fois que vous avez compris comment ils fonctionnent (et encore chaud / froid / chaud ne concerne que les effets secondaires lors de la souscription / observation ) ils peuvent être apprivoisés.Dans les deux mondes, le concept d'abonnement est fondamentalement le même, il y a une petite différence que RAC a introduit et c'est l'
interruption
événement quand unSignal
est supprimé avant l'envoi de l'événement d'achèvement. Pour récapituler, les deux ont le type d'événement suivant:Next
, pour calculer la nouvelle valeur reçueError
, pour calculer une erreur et terminer le flux, en désinscrivant tous les observateursComplete
, pour marquer le flux comme terminé en désinscrivant tous les observateursRAC a en plus
interrupted
qui est envoyé quand unSignal
est supprimé avant de terminer correctement ou avec une erreur.Écriture manuelle
Dans RAC,
Signal
/SignalProducer
sont des entités en lecture seule, elles ne peuvent pas être gérées de l'extérieur, c'est la même choseObservable
dans RxSwift. Pour transformer unSignal
/SignalProducer
en une entité accessible en écriture, vous devez utiliser lapipe()
fonction pour renvoyer un élément contrôlé manuellement. Sur l'espace Rx, il s'agit d'un type différent appeléSubject
.Si le concept de lecture / écriture ne vous est pas familier, une bonne analogie avec
Future
/Promise
peut être faite. AFuture
est un espace réservé en lecture seule, commeSignal
/SignalProducer
etObservable
, d'autre part, aPromise
peut être rempli manuellement, comme pourpipe()
etSubject
.Planificateurs
Cette entité est à peu près similaire dans les deux mondes, dans les mêmes concepts, mais RAC est uniquement en série, mais RxSwift propose également des planificateurs simultanés.
Composition
La composition est la caractéristique clé de la programmation réactive. La composition de flux est l'essence des deux frameworks, dans RxSwift, ils sont également appelés séquences .
Toutes les entités observables dans RxSwift sont de type
ObservableType
, donc nous composons des instances deSubject
etObservable
avec les mêmes opérateurs, sans souci supplémentaire.Sur l' espace RAC,
Signal
etSignalProducer
sont 2 entités différentes et nous devonslift
leSignalProducer
pouvoir de composer ce qui est produit avec des instances deSignal
. Les deux entités ont leurs propres opérateurs, donc lorsque vous devez mélanger des choses, vous devez vous assurer qu'un certain opérateur est disponible, de l'autre côté, vous oubliez les observables chaud / froid.À propos de cette partie, Colin Eberhardt l'a bien résumé:
Supplémentaire
RAC a également le concept de
Action
etProperty
, le premier est un type pour calculer les effets secondaires, principalement liés à l'interaction avec l'utilisateur, le second est intéressant lors de l'observation d'une valeur pour effectuer une tâche lorsque la valeur a changé. Dans RxSwift, leAction
traduit à nouveau en uneObservable
, c'est bien illustré dansRxCocoa
, une intégration des primitives Rx pour iOS et Mac. Les RACProperty
peuvent être traduits enVariable
(ouBehaviourSubject
) dans RxSwift.Il est important de comprendre que
Property
/Variable
est la façon dont nous devons faire le pont entre le monde impératif et la nature déclarative de la programmation réactive, donc est parfois un composant fondamental lorsqu'il s'agit de bibliothèques tierces ou de fonctionnalités de base de l'espace iOS / Mac.Conclusion
RAC et RxSwift sont 2 bêtes complètement différentes, la première a une longue histoire dans l'espace Cocoa et beaucoup de contributeurs, la seconde est assez jeune, mais s'appuie sur des concepts qui se sont avérés efficaces dans d'autres langages comme Java, JS ou .NET. La décision qui est la meilleure est la préférence. RAC déclare que la séparation du chaud / du froid observable était nécessaire et que c'est la caractéristique principale du cadre, RxSwift dit que l'unification de ceux-ci est meilleure que la séparation, encore une fois, il s'agit de la façon dont les effets secondaires sont gérés / exécutés.
RAC 3.0 semble avoir introduit une complexité inattendue en plus de l'objectif principal de séparer les observables chaud / froid, comme le concept d'interruption, de diviser les opérateurs entre 2 entités et d'introduire un comportement impératif comme
start
commencer à produire des signaux. Pour certaines personnes, ces choses peuvent être une bonne chose ou même une fonctionnalité de tueur, pour d'autres, elles peuvent être simplement inutiles ou même dangereuses. Une autre chose à retenir est que RAC essaie de suivre autant que possible les conventions Cocoa, donc si vous êtes un développeur Cocoa expérimenté, vous devriez vous sentir plus à l'aise de travailler avec lui plutôt qu'avec RxSwift.RxSwift d'autre part vit avec tous les inconvénients comme les observables chaud / froid, mais aussi les bonnes choses, des extensions réactives. Passer de RxJS, RxJava ou Rx.Net à RxSwift est une chose simple, tous les concepts sont les mêmes, donc cela rend la recherche de matériel assez intéressante, peut-être le même problème que vous rencontrez maintenant, a été résolu par quelqu'un dans RxJava et la solution peut être réappliqué en tenant compte de la plate-forme.
Celui qui doit être choisi est définitivement une question de préférence, d'un point de vue objectif, il est impossible de dire lequel est le meilleur. La seule façon est de lancer Xcode et de les essayer tous les deux et de choisir celui qui vous convient le mieux. Il s'agit de 2 implémentations de concepts similaires, essayant d'atteindre le même objectif: simplifier le développement logiciel.
la source
NoError
) dans les types de flux eux-mêmes:Signal<T, E: ErrorType>
contreObservable<T>
. Ceci, ainsi que la séparation chaud / froid, fournit une quantité accrue d'informations au moment de la compilation que vous n'avez tout simplement pas avecRxSwift
.