重置定时器信号的最佳方法是什么?

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];
}];