2

我正在尝试从 5 个不同的 URL 获取 JSON 数据。网络请求可以并行执行,但响应必须按特定顺序处理。另外,我也想有单点的错误处理逻辑。

我现在拥有的代码如下所示。问题是,只有订阅signalFivesignalSix已被调用。所有其他信号的subscribeNext块从未被调用过。我怀疑问题是因为订阅发生在发生之后sendNext

有没有更好/标准的方法来执行这种请求?

- (RACSubject *)signalForFetchingFromRemotePath:(NSString *)remotePath
{
    RACSubject *signal = [RACSubject subject];

    [self.requestOperationManager GET:remotePath parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        for (id obj in responseObject) {
            [signal sendNext:obj];
        }
        [signal sendCompleted];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [signal sendError:error];
    }];

    return signal;
}

FMDatabase *db = [SomeDatabase defaultDatabase];
[db beginTransaction];

RACSubject *singalOne = [self signalForFetchingFromRemotePath:[self urlStringWithPath:SYNC_ONE_PATH]];
RACSubject *singalTwo = [self signalForFetchingFromRemotePath:[self urlStringWithPath:SYNC_TWO_PATH]];
RACSubject *singalThree = [self signalForFetchingFromRemotePath:[self urlStringWithPath:SYNC_THREE_PATH]];
RACSubject *singalFour = [self signalForFetchingFromRemotePath:[self urlStringWithPath:SYNC_FOUR_PATH]];
RACSubject *singalFive = [self signalForFetchingFromRemotePath:[self urlStringWithPath:SYNC_FIVE_PATH]];
RACSubject *singalSix = [self signalForFetchingFromRemotePath:[self urlStringWithPath:SYNC_SIX_PATH]];
RACSignal *combined = [RACSignal merge:@[singalOne, singalTwo, singalThree, singalFour, singalFive, singalSix]];

[combined subscribeError:^(NSError *error){
   [db rollback];
}];

[singalFive subscribeNext:^(NSDictionary *dict) {
  [ClassE save:dict];
} completed:^{
   [singalSix subscribeNext:^(NSDictionary *dict) {
       [ClassF save:dict];
   } completed:^{
       [singalOne subscribeNext:^(NSDictionary *dict){
           [ClassA save:dict];
       } completed:^{
           [singalTwo subscribeNext:^(NSDictionary *dict){
               [ClassB save:dict];
           } completed:^{
               [singalThree subscribeNext:^(NSDictionary *dict) {
                   [ClassC save:dict];
               } completed:^{
                   [singalFour subscribeNext:^(NSDictionary *dict){
                       [ClassD save:dict];
                   } completed:^{
                       NSLog(@"Completed");

                       [db commit];
                   }];
               }];
           }];
       }];
   }];
}];
4

2 回答 2

2

如果您需要强制执行特定命令,请使用+concat:而不是+merge:.

就其本身而言,连接意味着请求不会被并行执行。如果您想恢复该行为,您可以-replay在将每个信号传递给+concat:.

顺便说一句,嵌套订阅几乎总是一种反模式。通常有一个内置的运算符来做你想做的事。

于 2013-12-22T21:21:32.033 回答
0

我通常使用combineLatest

NSArray *signals = @[singalOne, singalTwo, singalThree, singalFour, singalFive, singalSix];
[[RACSignal combineLatest:signals] subscribeNext:^(RACTuple *values) {
  // All your values are here
} error:^(NSError *error) {
  // error
}];
于 2015-02-01T17:52:17.997 回答