我有两个 RACSignal
,其中一个是计时器,另一个指示有工作要做。由于工作指示有时不可靠,所以有计时器,它负责在精确通知不起作用时定期完成工作。
一般设置是:
RACSignal *signal = [RACSignal merge:@[
[[RACSignal interval:0.5 onScheduler:[RACScheduler scheduler]]
filter:^BOOL(__unused id _x) {
return isThereAProblemInDeliveringWork();
}],
incomingWorkSubject
]];
现在我希望 signal
在 incomingWorkSubject
完成后立即完成。因此,一般来说:只要任何输入信号完成,就完成合并信号。不幸的是,[RACSignal merge:...]
没有做我想做的事,显然是在等待所有传入信号完成。
实现该目标的 ReactiveCocoa 方式是什么?
最佳答案
最明显的方法是应用 -takeUntil:
,当提供的信号发送值或完成时完成信号。由于您只希望在 incomingWorkSubject
完成时完成,而不是在发送值时完成,因此请使用 -ignoreValues
.
为了便于阅读,我已将定时器信号提取到一个变量中。
RACSignal *timer = [[RACSignal
interval:0.5 onScheduler:[RACScheduler scheduler]]
filter:^BOOL(__unused id _x) {
return isThereAProblemInDeliveringWork();
}];
RACSignal *signal = [[RACSignal
merge:@[ incomingWorkSubject, timer ]]
takeUntil:[incomingWorkSubject ignoreValues]];
为了便于讨论,还有另一种方法可能符合要求。相反,使用上面定义的 timer
,使用 -sample:
对 incomingWorkSubject
进行采样。 .如何执行此操作取决于 incomingWorkSubject
的性质。如果它是一个 RACReplaySubject
,并且您知道一个值将可用,则可以直接对其进行采样。
RACSignal *signal = [RACSignal merge:@[
incomingWorkSubject,
[incomingWorkSubject sample:timer]
]];
但是,如果 incomingWorkSubject
是普通的 RACSubject
,那么您需要编写一个新信号以包含初始值,-startWith:
,因此 -sample:
有一个值在 timer
触发时发送。
RACSignal *signal = [RACSignal merge:@[
incomingWorkSubject,
[[incomingWorkSubject startWith:initialValue] sample:timer]
]];
用英语来说,这会创建一个信号,从 incomingWorkSubject
发送最新值,并且还会从 incomingWorkSubject
发送最近缓存的值,但只有在定期检查到isThereAProblemInDeliveringWork()
是肯定的。合并信号在 incomingWorkSubject
完成时完成。
关于objective-c - 合并两个 RACSignals,在第一次完成时完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18876140/