简体   繁体   中英

What's the best way to reset a timer signal?

I need to fetch data from server every 5 minutes. If I do pull down refresh, also need to fetch data from server, and reset the timer .

Below code is the solution now, looks works fine. Just wonder how to simplify the code? Probable there's better way in 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];
        }];
    }];

The cleanest way that I can think of would be using a RACReplaySubject , sending interval signals of 300 and then switching to the latest signal sent every time the block is fired.

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

I would map the refreshSignal to a timer signal. Every time the refreshSignal sends a value it is mapped to a signal sending a value every five minutes.

As a side note I think this logic belongs in the view model. There the resulting signal could be mapped to a network request with flatMap: . Then an ongoing network request would be cancelled if the user refreshes again quickly.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM