2016-07-15 31 views
1

我想並行發起多個獨立網絡請求,並訂閱所有請求完成(我不在乎它們是否完成或錯誤)。現在我用combineLatest。因此這些請求是並行的(正如我想的那樣),但是當一個信號發送error時,我在訂閱中遇到錯誤。Reactive Cocoa Legacy - 如何並行處理多個獨立信號?

我找不到一個運算符,它允許我並行地啓動多個獨立請求,並在完成所有操作時收聽。

此致

EDIT

在其他情況下(其中,我需要使用單獨的信號),我需要訂閱的誤差。所以我仍然需要我的信號能夠sendError:

我的使用情況是這樣的:

,一方面,我有一個應用程序,可以做到完全同步。這將啓動所有獨立請求。我需要知道何時完成所有請求才能解除進度HUD。我不在乎我的信號是否已完成sendErrorsendCompleted。但另一方面,我有多個按鈕,我可以在每個請求中單獨重新啓動,在這種情況下,我需要告訴用戶信號是成功還是失敗。

回答

1

我想出了一個答案,使用catch操作: 我添加catch RAC操作我所有的信號,即在情況下,信號作出新的[RACSignal empty]失敗:

NSArray* allSignals = @[signal1, signal2, signal3, signal4]; 
NSMutableArray* optionalSignals = [NSMutableArray array]; 
    for (RACSignal* signal in allSignals) { 
     RACSignal* catchableSignal = [signal catch:^RACSignal *(NSError *error) { 
      return [RACSignal empty]; 
     }]; 
     [optionalSignals addObject:catchableSignal]; 
    } 

return [RACSignal combineLatest:optionalSignals]; 

這不會改變我的個別信號的性質,我從combineLatest功能中獲益。

編輯

如果任何人有一個更優雅的RAC的方法來處理for ... in循環,我仍然有興趣。

0

你可以試試這個代碼:

- (void)getAllItemsWithCompletion:(void (^)())completion { 
     NSArray *signals = [self.allItems.rac_sequence map:^id(Item *item) { 
      return [[[self getForItemSignal:item] doCompleted:^{ 
         //done 
        }] doError:^(NSError *error) { 
         //Change the button title to retry 
        }]; 
    }].array; 

    [[RACSignal combineLatest:signals] subscribeCompleted:^{ 
    NSLog(@"All tasks are done"); 
    }]; 
} 

- (RACSignal *)getForItemSignal:(Item *)item { 
return [RACSignal startEagerlyWithScheduler:[RACScheduler scheduler] block:^(id<RACSubscriber> subscriber) { 
     [APIClient getFeeForItemUUID:item.UUID 
         success:^(Fee *fee) { 
          [subscriber sendNext:@(fee)]; 
          [subscriber sendCompleted]; 
         } 
         failure:^(NSError *error) { 
          [subscriber sendError:error]; 
          [subscriber sendCompleted]; 
         }]; 
    }]; 
} 
+0

謝謝,我會嘗試 – darksider

+0

我明白了,你不做發送錯誤,所以combineLatest去在完成。這是個好主意。但在某些情況下,我個別使用信號,在這種情況下,我需要知道是否有錯誤。你知道在不改變信號性質的情況下是否可以實現相同的結果,而是通過與RAC操作員一起玩? – darksider

+0

@darksider像你一樣顯示按鈕還有每個請求嗎? –

1

您可以使用rac_sequencemap代替循環。另外,在使用catchTo您的案件將在相同的方式工作爲catch,同時使代碼更簡潔:

NSArray* allSignals = @[signal1, signal2, signal3, signal4]; 
RACSequence *optionalSignals = [[allSignals rac_sequence] map:^id(RACSignal *signal) { 
      return [signal catchTo:[RACSignal empty]]; 
}]; 

return [RACSignal combineLatest:optionalSignals];