[英]ReactiveCocoa vs RxSwift - pros and cons?
So now with swift, the ReactiveCocoa people have rewritten it in version 3.0 for swift 所以现在有了swift, ReactiveCocoa人员已经在3.0版本中为swift重写了它
Also, there's been another project spun up called RxSwift . 此外,还有另一个名为RxSwift的项目。
I wonder if people could add information about what the differences in design/api/philosophy of the two frameworks are (please, in the spirit of SO, stick to things which are true, rather than opinions about which is "best") 我想知道人们是否可以添加关于两个框架的设计/ api /哲学的差异的信息(请在SO的精神中,坚持真实的事情,而不是关于哪个是“最好的”的意见)
[Note for StackOverflow mods: This question DOES have definitive answers, the answer is the differences between the two frameworks. [注意StackOverflow mods:这个问题有确切的答案,答案是两个框架之间的差异。 I think it is also highly on topic for SO]
我认为这也是SO的主题
To get started, my initial impression from reading their ReadMe's is: 首先,我阅读ReadMe的最初印象是:
This is a very good question. 这个问题问得好。 Comparing the two worlds is very hard.
比较两个世界是非常困难的。 Rx is a port of what Reactive Extensions are in other languages like C#, Java or JS.
Rx是Reactive Extensions在其他语言(如C#,Java或JS)中的端口。
Reactive Cocoa was inspired by Functional Reactive Programming , but in the last months, has been also pointed as inspired by Reactive Extensions as well. Reactive Cocoa的灵感来自功能反应式编程 ,但在过去的几个月中,也被反应性扩展所启发 。 The outcome is a framework that shares some things with Rx, but has names with origins in FRP.
结果是一个与Rx共享某些东西的框架,但其名称起源于FRP。
The first thing to say is that neither RAC nor RxSwift are Functional Reactive Programming implementations, according to Conal's definition of the concept. 首先要说的是,根据Conal对概念的定义 ,RAC和RxSwift都不是功能反应式编程实现。 From this point everything can be reduced to how each framework handles side effects and a few other components.
从这一点来看,一切都可以简化为每个框架如何处理副作用和一些其他组件。
Let's talk about the community and meta-tech stuff: 我们来谈谈社区和元技术的东西:
Now it's time for the tech stuff. 现在是技术人员的时候了。
RAC 3.0 has 2 main entities, Signal
and SignalProducer
, the first one publishes events regardless a subscriber is attached or not, the second one requires a start
to actually having signals/events produced. RAC 3.0有2个主要实体,
Signal
和SignalProducer
,第一个发布事件而不管用户是否连接,第二个实体需要start
实际生成信号/事件。 This design has been created to separate the tedious concept of hot and cold observables, that has been source of confusion for a lot of developers. 这个设计是为了区分热和冷可观察的乏味概念而创建的,这对很多开发人员来说都是混乱的根源。 This is why the differences can be reduced to how they manage side effects .
这就是为什么差异可以减少到他们如何管理副作用 。
In RxSwift, Signal
and SignalProducer
translates to Observable
, it could sound confusing, but these 2 entities are actually the same thing in the Rx world. 在RxSwift中,
Signal
和SignalProducer
转换为Observable
,它可能听起来令人困惑,但这两个实体在Rx世界中实际上是相同的。 A design with Observable
s in RxSwift has to be created considering if they are hot or cold, it could sound as unnecessary complexity, but once you understood how they work (and again hot/cold/warm is just about the side effects while subscribing/observing) they can be tamed. RxSwift中的
Observable
设计必须考虑它们是热还是冷,它听起来可能是不必要的复杂性,但是一旦你理解了它们是如何工作的(再次热/冷/温暖就是订阅时的副作用/观察)他们可以被驯服。
In both worlds, the concept of subscription is basically the same, there's one little difference that RAC introduced and is the interruption
event when a Signal
is disposed before the completion event has been sent. 在这两个世界中,订阅的概念基本相同,RAC引入的一点点差异是在发送完成事件之前处理
Signal
时的interruption
事件。 To recap both have the following kind of events: 回顾两者都有以下类型的事件:
Next
, to compute the new received value Next
,计算新接收的值 Error
, to compute an error and complete the stream, unsubscribing all the observers Error
,计算错误并完成流,取消订阅所有观察者 Complete
, to mark the stream as completed unsubscribing all observers Complete
,将流标记为已完成取消订阅所有观察者 RAC in addition has interrupted
that is sent when a Signal
is disposed before completing either correctly or with an error. 此外,RAC在
Signal
处理之前发送interrupted
,在正确完成或出错之前发送Signal
。
In RAC, Signal
/ SignalProducer
are read-only entities, they can't be managed from outside, same thing is for Observable
in RxSwift. 在RAC中,
Signal
/ SignalProducer
是只读实体,它们不能从外部管理,RxSwift中的Observable
也是如此。 To turn a Signal
/ SignalProducer
into a write-able entity, you have to use the pipe()
function to return a manually controlled item. 要将
Signal
/ SignalProducer
转换为可写实体,必须使用pipe()
函数返回手动控制的项目。 On the Rx space, this is a different type called Subject
. 在Rx空间中,这是一个名为
Subject
的不同类型。
If the read/write concept sounds unfamiliar, a nice analogy with Future
/ Promise
can be made. 如果读/写概念听起来不熟悉,可以与
Future
/ Promise
进行很好的类比。 A Future
is a read-only placeholder, like Signal
/ SignalProducer
and Observable
, on the other hand, a Promise
can be fulfilled manually, like for pipe()
and Subject
. Future
是一个只读占位符,如Signal
/ SignalProducer
和Observable
,另一方面, Promise
可以手动完成,比如pipe()
和Subject
。
This entity is pretty much similar in both worlds, same concepts, but RAC is serial-only, instead RxSwift features also concurrent schedulers. 这个实体在两个世界中都是相似的,相同的概念,但RAC只是串行的,而RxSwift也是并发调度器。
Composition is the key feature of Reactive Programming. 组合是反应式编程的关键特性。 Composing streams is the essence of both frameworks, in RxSwift they are also called sequences .
组合流是两个框架的本质,在RxSwift中它们也称为序列 。
All the observable entities in RxSwift are of type ObservableType
, so we compose instances of Subject
and Observable
with the same operators, without any extra concern. RxSwift中的所有可观察实体都是
ObservableType
类型,因此我们使用相同的运算符组合Subject
和Observable
实例,而不需要任何额外的关注。
On RAC space, Signal
and SignalProducer
are 2 different entities and we have to lift
on SignalProducer
to be able to compose what is produced with instances of Signal
. 在RAC领域,
Signal
和SignalProducer
是两个不同的实体,我们必须lift
SignalProducer
才能组合Signal
实例产生的内容。 The two entities have their own operators, so when you need to mix things, you have to make sure a certain operator is available, on the other side you forget about the hot/cold observables. 这两个实体有自己的操作符,所以当你需要混合时,你必须确保某个操作符可用,另一方面你忘记了热/冷可观察量。
About this part, Colin Eberhardt summed it nicely: 关于这一部分, Colin Eberhardt很好地总结了这一点:
Looking at the current API the signal operations are mainly focussed on the 'next' event, allowing you to transform values, skip, delay, combine and observe on different threads.
查看当前的API,信号操作主要关注“下一个”事件,允许您在不同的线程上转换值,跳过,延迟,组合和观察。 Whereas the signal producer API is mostly concerned with the signal lifecycle events (completed, error), with operations including then, flatMap, takeUntil and catch.
而信号生成器API主要关注信号生命周期事件(已完成,错误),其中包括flatMap,takeUntil和catch等操作。
RAC has also the concept of Action
and Property
, the former is a type to compute side effects, mainly relating to user interaction, the latter is interesting when observing a value to perform a task when the value has changed. RAC还有
Action
和Property
的概念,前者是一种计算副作用的类型,主要与用户交互有关,后者在观察值以改变值时执行任务时很有意义。 In RxSwift the Action
translates again into an Observable
, this is nicely shown in RxCocoa
, an integration of Rx primitives for both iOS and Mac. 在RxSwift中,
Action
再次转换为Observable
,这在RxCocoa
很好地展示, RxCocoa
是iOS和Mac的Rx原语的集成。 The RAC's Property
can be translated into Variable
(or BehaviourSubject
) in RxSwift. RAC的
Property
可以在RxSwift中转换为Variable
(或BehaviourSubject
)。
It's important to understand that Property
/ Variable
is the way we have to bridge the imperative world to the declarative nature of Reactive Programming, so sometimes is a fundamental component when dealing with third party libraries or core functionalities of the iOS/Mac space. 重要的是要理解
Property
/ Variable
是我们必须将命令式世界与反应式编程的声明性本质联系起来的方式,因此有时在处理第三方库或iOS / Mac空间的核心功能时是一个基本组件。
RAC and RxSwift are 2 complete different beasts, the former has a long history in the Cocoa space and a lot of contributors, the latter is fairly young, but relies on concepts that have been proven to be effective in other languages like Java, JS or .NET. RAC和RxSwift是两个完全不同的野兽,前者在Cocoa领域有很长的历史和很多贡献者,后者相当年轻,但依赖于已被证明在Java,JS或其他语言中有效的概念。净。 The decision on which is better is on preference.
关于哪个更好的决定取决于偏好。 RAC states that the separation of hot/cold observable was necessary and that is the core feature of the framework, RxSwift says that the unification of them is better than the separation, again it's just about how side effects are managed/performed.
RAC指出热/冷可观察的分离是必要的,这是该框架的核心特征,RxSwift说它们的统一优于分离,再次只是关于如何管理/执行副作用。
RAC 3.0 seems to have introduced some unexpected complexity on top of the major goal of separating hot/cold observables, like the concept of interruption, splitting operators between 2 entities and introducing some imperative behaviour like start
to begin producing signals. RAC 3.0似乎已经介绍的分离热/冷可观,像中断2个实体之间的概念,拆分运营商和引进像一些必要的行为的主要目标顶部一些意想不到的复杂性
start
,开始产生信号。 For some people these things can be a nice thing to have or even a killer feature, for some others they can be just unnecessary or even dangerous. 对于某些人来说,这些东西可能是一件好事,甚至是一个杀手级的功能,对于其他人来说,这些东西可能只是不必要甚至是危险的。 Another thing to remember is that RAC is trying to keep up with Cocoa conventions as much as possible, so if you are an experienced Cocoa Dev, you should feel more comfortable to work with it rather than RxSwift.
另一件需要记住的事情是RAC试图尽可能地遵守Cocoa约定,所以如果你是一个经验丰富的Cocoa Dev,你应该感觉更舒服,而不是RxSwift。
RxSwift on the other hand lives with all the downsides like hot/cold observables, but also the good things, of Reactive Extensions. 另一方面,RxSwift存在所有缺点,如热/冷可观测量,但也有反应性扩展的好处。 Moving from RxJS, RxJava or Rx.Net to RxSwift is a simple thing, all the concepts are the same, so this makes finding material pretty interesting, maybe the same problem you are facing now, has been solved by someone in RxJava and the solution can be reapplied taking in consideration the platform.
从RxJS,RxJava或Rx.Net迁移到RxSwift是一件简单的事情,所有概念都是相同的,所以这使得查找材料非常有趣,可能是您现在面临的同样问题,已经被RxJava中的某个人解决了可以考虑平台重新应用。
Which one has to be picked is definitely a matter of preference, from an objective perspective is impossible to tell which one is better. 必须选择哪一个肯定是一个偏好的问题,从客观的角度来看,不可能分辨哪一个更好。 The only way is to fire Xcode and try both of them and pick the one that feels more comfortable to work with.
唯一的方法是解雇Xcode并试用它们并选择一个感觉更舒适的工作。 They are 2 implementations of similar concepts, trying to achieve the same goal: simplifying software development.
它们是类似概念的两种实现,试图实现相同的目标:简化软件开发。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.