我有两个要合并的网络信号,但有一些限制。
让我们将网络信号称为 A 和 B。A 确实使用 AFNetworking 在缓存中查找资源并立即返回对该请求的任何响应。B 也考虑缓存,但可以到远程服务器重新验证响应。
好的,所以我想做的是:
要求一:
- 应该尽快做 sendNext。
- 如果 B 已经完成了 sendNext,我们将忽略 A。
- 如果出现问题,并且 A 产生错误,我们应该忽略它。
请求 B:
- 应该尽快做 sendNext,即使 A 已经做了一个 sendNext。
- 如果出现问题,我对 B 的错误很感兴趣,但它不应该阻止 A。
我目前的解决方案是这样的:
- (RACSignal *)issueById:(NSString *)issueId {
RACSignal *filterSignal = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
RACSignal *cacheSignal = [[IssueWSRequest instance] issueWithId:issueId cachePolicy:NSURLRequestReturnCacheDataDontLoad];
return [cacheSignal subscribeNext:^(id x) {
[subscriber sendNext:x];
} error:^(NSError *error) {
NSLog(@"Ignore error");
[subscriber sendCompleted];
} completed:^{
[subscriber sendCompleted];
}];
}];
RACSignal *remoteSignal = [[IssueWSRequest instance] issueWithId:issueId cachePolicy:NSURLRequestUseProtocolCachePolicy];
RACSignal *combined = [RACSignal merge:@[newSign, remoteSignal]];
return combined;
}
我知道这个解决方案不能满足我的要求,所以我想知道是否有人可以帮助我提供更好的解决方案。
我的解决方案(来自@JustinSpahr-Summers 的回答):
- (RACSignal *)issueById:(NSString *)issueId {
RACSubject *localErrors = [RACSubject subject];
RACSignal *remoteSignal = [[IssueWSRequest instance] issueWithId:issueId cachePolicy:NSURLRequestUseProtocolCachePolicy];
RACSignal *cacheSignal = [[[[[[IssueWSRequest instance] issueWithId:issueId cachePolicy:NSURLRequestReturnCacheDataDontLoad]
takeUntil:remoteSignal] doError:^(NSError *error) {
[localErrors sendNext:error];
}] finally:^{
// Make sure to complete the subject, since infinite signals are
// difficult to use.
[localErrors sendCompleted];
}]
replayLazily];
return [RACSignal merge:@[
[cacheSignal catchTo:[RACSignal empty]],
remoteSignal
]];
}