How to merge multiple signal and stop on first next but not to stop on first error?

305 views Asked by At

I have a number of network requests and one or more of them will return valid data and is possible that some will return an error. How can I combine this request to stop once the first valid returned the data but not to stop in case of error.

I have try like this:

[[RACSignal merge:@[sigOne, sigTwo, sigThree]]
        subscribeNext:^(RACTuple *myData){
            NSLog(@"Data received");
        } error:^(NSError *error) {
            NSLog(@"E %@", error);
        }
        completed:^{
            NSLog(@"They're all done!");
        }
     ];

My problems:

  • if one of the signals returns first with error then no next will be send. Not desired because one of the other signals will return valid data.
  • if all three return valid data then the subscribeNext will be called three times but I would like to stop as soon I got some valid data (to reduce network traffic)
1

There are 1 answers

2
Charles Maria On BEST ANSWER

Try this:

[[[[RACSignal merge:@[[sigOne catchTo:[RACSignal empty]], 
                      [sigTwo catchTo:[RACSignal empty]], 
                      [sigThree catchTo:[RACSignal empty]]]] 
                          repeat] take:1]
    subscribeNext:^(RACTuple *myData){
        NSLog(@"Data received");
    } error:^(NSError *error) {
        NSLog(@"E %@", error);
    }
    completed:^{
        NSLog(@"They're all done!");
    }
 ];

By using catchTo:, the signals are being replaced with an empty signal when they error, which just causes the signal to send complete, and doesn't end the subscription for every other signal. By adding repeat, we're getting the signal to run again if no next events occurred (because all of the signals errored). By adding take:1, the signal will complete once a single next event is received.