ReactiveCocoa - 停止触发subscribeNext,直到另一个信号完成

时间:2015-09-16 14:45:23

标签: ios swift reactive-programming reactive-cocoa

我对FRP很新,我遇到了一个问题:

我订阅了一个每秒触发subscribeNext的观察者。

subscribeNext的块中,I zip可执行异步操作的可观察对象,并且在zip的{​​{1}}块中,我对结果执行操作。

completed

我希望停止触发let signal: RACSignal let asynchOperations: [RACSignal] var val: AnyObject? // subscribeNext is trigered every second signal.subscribeNext { let asynchOperations = // several RACSignal // Perform asynchronous operations RACSignal.zip(asynchOperations).subscribeNext({ val = $0 }, completed: { // perform actions with `val` }) } subscribeNext(通常每秒触发一次),直到signal(来自completed)。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

听起来你想要RACCommand

命令是一个可以执行异步操作的对象,但一次只能运行一个操作实例。一旦您告诉命令启动execute:,它将被“禁用”,并在操作完成后自动再次启用。

(您还可以根据其他标准创建一个启用的命令,而不仅仅是“我现在正在执行”,但这听起来并不像您需要的那样。)

一旦你有了这个,你可以得到一个“门控”间隔信号的信号(例如,if:then:else:在命令的enabled信号之间切换{{1}和你的实际信号 - 我这么做,我有一个帮助器),或者你可以在订阅块中调用RACSignal.empty之前检查canExecute属性。

注意:你在内部订阅时做了一些有点奇怪的事情 - 捕获值然后处理已完成块上的值。

如果你这样做是因为它更明确,并且你知道信号只发送一个值,但你觉得需要直接编码,那就没关系。我不认为它是标准的 - 如果你有一个只发送一个值的信号,那不幸的是无法在类型级别表示,但仍然是你可以在你的代码中做出的假设(或者至少,我觉得自己对这个假设感到满意。对每个人都这样做。

但是如果你是出于时间原因而做的,或者因为你实际上只想要从信号发送 last 值,你可以使用execute:来获得一个信号总是在内部信号完成时恰好发送一个值,然后只在takeLast:1块中订阅。

轻微警告:next s用于从主线程用于支持UI更新;如果你想在后台线程上使用命令,你需要明确关于调度程序来发送你的信号(查看文档以获取更多细节)。

获得类似行为的另一种完全不同的方法是时间递归:执行操作,然后在完成后,安排操作在一秒钟后再次发生,而不是持续计时器。

这略有不同,因为你总是在操作之间等待一秒,而在当前的那个你可以等待零到一秒之间的任何地方,但如果这不是问题那么这个是一个比使用RACCommand更简单的解决方案。

ReactiveCocoa的RACCommand方法使这种临时调度变得非常方便 - 这里没有人工delay:争论。