2015-08-21 4 views
1

Мне нужно получать данные с сервера каждые 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]; 
     }]; 
    }]; 

ответ

1

Чистейшая способ, которым я могу думать, было бы с помощью RACReplaySubject, посылая сигналы interval 300, а затем переход к последнему сигнала, посланного каждый раз, когда блок увольняют.

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

Да, ваш код намного чище, чем мой. Просто не знакомы с RACReplaySubject. – JerryZhou

+0

'RACReplaySubject' - это своего рода« ручной »сигнал. Это похоже на изменяемый переменный эквивалент функционального реактивного мира. Вы скажете его вручную, когда нужно отправить 'next',' error' и 'completed'. Поскольку он имеет емкость '1', он сохраняет последний отправленный' next' и перенаправляет его на любые новые подписки. –

+1

Я проверил ваш код, только одна небольшая проблема (или может быть его особенностью): задержка может задержать 300 или 301 секунд, и он не любит таймер с функциейLeeway, чтобы сделать смещение интервала; Какой таймер дает, если это 301 секунд, в следующий раз он может вернуться к 209 секундам, чтобы сделать его соболиным. – JerryZhou

0

Я бы обозначил 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]; 
}]; 
+0

Благодарим вас за повторную игру, я проверю позже. – JerryZhou

Смежные вопросы