Reputation: 1120
I have 2 network signals and the first one needs to complete before the next one starts because I need to send an accessToken
for the second request and I obtain that in the first request. Then I want to reduce the values from each step into a single object. I guess combineLatest:reduce:
subscribes to both of them and has nothing to do with waiting completion of signal.
I have this right now:
- (RACSignal *)loginWithEmail:(NSString *)email password:(NSString *)password
{
@weakify(self);
RACSignal *authSignal = [[self requestTokensWithUsername:email password:password]
doNext:^(Authentication *auth) {
@strongify(self);
self.authentication = auth;
}];
RACSignal *profileSignal = [self fetchProfile];
NSArray *orderedSignals = @[ authSignal, profileSignal ];
RACSignal *userSignal =
[RACSignal combineLatest:orderedSignals
reduce:^id(Authentication *auth, Profile *profile) {
NSLog(@"combine: %@, %@", auth, profile);
return [User userWithAuth:auth profile:profile history:nil];
}];
return [[[RACSignal concat:orderedSignals.rac_sequence] collect]
flattenMap:^RACStream * (id value) {
return userSignal;
}];
}
To ensure that they are done in order, I return a signal where I first concat:
the signals, then collect
them to send completed only when all of the signals complete, and flattenMap:
to a combineLatest:reduce:
to process latest result from each.
It works but I think there might be a more concise and better way to do this. How might I rewrite this part to make it more concise maybe?
Upvotes: 2
Views: 1644
Reputation: 1120
FWIW, I simplified my code to this and somewhat happy with the results. I'm leaving it here for future reference.
- (RACSignal *)loginWithEmail:(NSString *)email password:(NSString *)password
{
@weakify(self);
RACSignal *authSignal = [[self requestTokensWithUsername:email password:password]
doNext:^(Authentication *auth) {
@strongify(self);
self.authentication = auth;
}];
RACSignal *profileSignal = [self fetchProfile];
RACSignal *historySignal = [self fetchHistory];
RACSignal *balanceSignal = [self fetchBalanceDetails];
NSArray *orderedSignals = @[ authSignal, balanceSignal, profileSignal, historySignal ];
return [[[RACSignal concat:orderedSignals.rac_sequence]
collect]
map:^id(NSArray *parameters) {
return [User userWithAuth:parameters[0]
balance:parameters[1]
profile:parameters[2]
history:parameters[3]];
}];
}
Upvotes: 1
Reputation: 3041
Take look at - (RACSignal*)then:(RACSignal*(^)(void))block;
I think it perfectly fits to your case.
For example:
RACSignal* loginSignal = [[self authenticateWithUsername:username password:password] doNext:...];
RACSignal *resultSignal = [loginSignal then:^RACSignal* {
return [self fetchProfile];
}];
return resultSignal;
Upvotes: 2