这段回答来自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]
这缺乏任何过期刷新功能。为了实现这一点,让我们创建一个请求信号,在前一个请求完成后适当的-delay
后-repeat
:
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]