Ответ 1
Ответ, скопированный с GitHub
Ответ может идти по-разному, установка не предлагает больших ограничений. В этом случае я сделаю несколько советов, чтобы начать разговор.
Во-первых, взгляните на +merge:
, который позволяет комбинировать коллекцию сигналов путем "переброски" их значений в один сигнал.
RACSignal *deckInvalidated = [[RACSignal merge:@[
userDidSomethingSignal,
appReawokenSignal,
// etc
]];
При этом нам нужно преобразовать этот сигнал в тот, который извлекает колоды с сервера всякий раз, когда происходит событие недействительности.
Прежде чем мы сможем это сделать, давайте посмотрим, как выглядит запрос сигнала. Предположим, что у вас есть клиент RACified API.
RACSignal *fetchDecks = [[APIClient fetchDecks] startWith:nil];
Использование -startWith:
- это немного вперед мышления в этой точке. План состоит в том, чтобы сформировать сигнал, который будет "привязан" к свойству с использованием макроса RAC
, и с помощью startWith:nil
это свойство будет установлено на nil
всякий раз, когда начнется новый запрос. Это должно соответствовать вашим требованиям:
сначала ничего не показывать (вместо того, чтобы показывать старый список, так как он знает его устаревшим из-за действия пользователя) и повторно отобразит список
Теперь мы можем отображать события недействительности в сетевой запрос, и это будет выглядеть довольно просто, но ему не хватает некоторых вещей.
RAC(self, decks) = [[deckInvalidated mapReplace:fetchDecks] switchToLatest];
В этом не хватает освежающего времени. Чтобы сделать это, дайте сигнал запроса -repeat
после соответствующего -delay
после завершения предыдущего запроса:
RACSignal *delay = [[RACSignal empty] delay:AEDeckRefreshTimeout];
RACSignal *repeatingFetchDecks = [[fetchDecks concat:delay] repeat];
Теперь, пересматривая назначение RAC
, его нужно лишь слегка изменить:
RAC(self, decks) = [[deckInvalidated mapReplace:repeatingFetchDecks] switchToLatest];
По-прежнему существует проблема с тем, что события недействительности вызывают параллельные запросы на сервер. Вы не упомянули об этом как о проблеме, поэтому не уверены, что это необходимо/важно для ваших случаев использования приложений, но что-то нужно учитывать.
Для полного обзора код может быть выполнен в одной композиции сигнала:
RAC(self, decks) = [[[RACSignal
merge:@[
userDidSomethingSignal,
appReawokenSignal,
]]
mapReplace:[[[[APIClient
fetchDecks]
startWith:nil]
concat:[[RACSignal
empty]
delay:AEDeckRefreshTimeout]]
repeat]]
switchToLatest];