重置定时器信号的最佳方法是什么?
What's the best way to reset a timer signal?
我需要每 5 分钟从服务器获取一次数据。如果我下拉刷新,还需要从服务器获取数据,并且重置定时器。
下面的代码是现在的解决方案,看起来工作正常。只是想知道如何简化代码? ReactiveCocoa
中可能有更好的方法?
RACSignal* refreshSignal = [self.refreshControl rac_signalForControlEvents:UIControlEventValueChanged];
self.timerSignal = [[RACSignal interval:300 onScheduler:[RACScheduler scheduler] withLeeway:2] takeUntil:refreshSignal];
[self.timerSignal subscribeNext:^(id x) {
NSLog(@"==========================");
NSLog(@"[Timer1]");
[self.viewModel performFetch];
}];
[refreshSignal subscribeNext:^(id x) {
NSLog(@"==========================");
NSLog(@"[Refresh]");
[self.viewModel performFetch];
self.timerSignal = [[RACSignal interval:300 onScheduler:[RACScheduler scheduler] withLeeway:2] takeUntil:refreshSignal];
[self.timerSignal subscribeNext:^(id x) {
NSLog(@"==========================");
NSLog(@"[Timer2]");
[self.viewModel performFetch];
}];
}];
我能想到的最简洁的方法是使用 RACReplaySubject
,发送 300 个 interval
信号,然后在每次触发块时切换到发送的最新信号。
self.timerSubject = [RACReplaySubject replaySubjectWithCapacity:1];
RACSignal * refreshSignal = [self.refreshControl rac_signalForControlEvents:UIControlEventValueChanged];
RACSignal * timeSignal = [RACSignal interval:300 onScheduler:[RACScheduler scheduler] withLeeway:2];
[self.timerSubject sendNext:timeSignal];
@weakify(self)
[[self.timerSubject.switchToLatest merge:refreshSignal] subscribeNext:^(id _) {
@strongify(self)
[self.viewModel performFetch];
}];
[refreshSignal subscribeNext:^(id _) {
@strongify(self)
[self.timerSubject sendNext:timeSignal];
}];
我会将 refreshSignal 映射到定时器信号。每次 refreshSignal 发送一个值时,它都会映射到一个每五分钟发送一个值的信号。
附带说明一下,我认为这个逻辑属于视图模型。结果信号可以映射到 flatMap:
的网络请求。如果用户再次快速刷新,则正在进行的网络请求将被取消。
[[[[refreshSignal startWith:nil]
map:^id(id value) {
return [[RACSignal interval:5 * 60 onScheduler:[RACScheduler mainThreadScheduler]] startWith:nil];
}]
switchToLatest]
subscribeNext:^(id x) {
@strongify(self)
[self.viewModel performFetch];
}];