合并和减少,但在订阅下一个信号之前等待每个信号完成
Combine and reduce but wait for each signal to complete before subscribing to next one
我有 2 个网络信号,第一个需要在下一个开始之前完成,因为我需要为第二个请求发送 accessToken
,我在第一个请求中获得了它。然后我想将每个步骤的值减少到一个对象中。我想 combineLatest:reduce:
订阅了他们两个,与等待信号完成无关。
我现在有这个:
- (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;
}];
}
为了确保它们按顺序完成,我 return 一个信号,我首先 concat:
信号,然后 collect
它们仅在所有信号完成时才发送完成, 和 flattenMap:
到 combineLatest:reduce:
以处理每个的最新结果。
它有效,但我认为可能有更简洁、更好的方法来做到这一点。我该如何重写这部分以使其更简洁?
看看- (RACSignal*)then:(RACSignal*(^)(void))block;
我认为它非常适合您的情况。
例如:
RACSignal* loginSignal = [[self authenticateWithUsername:username password:password] doNext:...];
RACSignal *resultSignal = [loginSignal then:^RACSignal* {
return [self fetchProfile];
}];
return resultSignal;
FWIW,我将我的代码简化为这个并且对结果有些满意。我把它留在这里供将来参考。
- (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]];
}];
}
我有 2 个网络信号,第一个需要在下一个开始之前完成,因为我需要为第二个请求发送 accessToken
,我在第一个请求中获得了它。然后我想将每个步骤的值减少到一个对象中。我想 combineLatest:reduce:
订阅了他们两个,与等待信号完成无关。
我现在有这个:
- (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;
}];
}
为了确保它们按顺序完成,我 return 一个信号,我首先 concat:
信号,然后 collect
它们仅在所有信号完成时才发送完成, 和 flattenMap:
到 combineLatest:reduce:
以处理每个的最新结果。
它有效,但我认为可能有更简洁、更好的方法来做到这一点。我该如何重写这部分以使其更简洁?
看看- (RACSignal*)then:(RACSignal*(^)(void))block;
我认为它非常适合您的情况。
例如:
RACSignal* loginSignal = [[self authenticateWithUsername:username password:password] doNext:...];
RACSignal *resultSignal = [loginSignal then:^RACSignal* {
return [self fetchProfile];
}];
return resultSignal;
FWIW,我将我的代码简化为这个并且对结果有些满意。我把它留在这里供将来参考。
- (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]];
}];
}