如何等到任务完成然后 return 一个信号,反应 cocoa
how to wait until the task is completed and then return a signal, reactive cocoa
-(RACSignal*)finalPackage {
RACSignal *endPoint = [[DGConfiguration sharedInstance].apiConfiguration
urlTemplate:DGAPIUrlLocalWatchList];` // 1.
return [[endPointRequestSignal map:^id(NSString *endPoint) { // 2.
return service([NSURL URLWithString: endPoint]);
}].flatten map:^id(NSArray *episodes) { // 3.
NSMutableArray *info= [NSMutableArray array];
__block NSArray *result=@[@(9)]; // test value is 9, result will be updated during callback block
[episodes enumerateObjectsUsingBlock:^(NSDictionary *item, NSUInteger idx, BOOL *stop) {
[info addObject:@{@"id":item[@"id"],@"links":item[@"links"]}];
}];
[[DGManager sharedInstance] updateVideoStateWith:info callback:^(NSArray *response) { // 4.
dispatch_async(dispatch_get_main_queue(), ^{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
result = [[response sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]] copy];
});
}];
return [RACSignal return:result]; // 5.
}].flatten;
}
让我解释一下我想做什么。
- 我通过
endPoint
信号 包裹端点 url
- 使用
map
提取 url 并执行服务调用 (service([NSURL URLWithString: endPoint])
)
- 使用
map
从步骤 2 中提取信息并创建 info
数据
- 使用回调
updateVideoStateWith
- Return 包含
result
的信号
最终,当我订阅finalPackage
信号时,return初始化为9
。我意识到updateVideoStateWith
回调需要时间return 结果。
我的问题是如何强制 return [RACSignal return:result]
等待数据从回调块更新。我确实尝试过 takeUntilBlock 但不确定如何使用它。我也考虑过使用 switchToLatest 但还是不行。
交叉发布我在 GitHub 问题中的回答:
- (RACSignal*)finalPackage {
return [RACSignal createSignal:^(id<RACSubscriber> subscriber) {
RACSignal *endPointSignal = [[DGConfiguration sharedInstance].apiConfiguration urlTemplate:DGAPIUrlLocalWatchList];
[[endPointSignal map:^id(NSString *endPoint) {
// map your endpoints to episodes and return the array of episodes
}] subscribeNext:^(NSArray* episodes) {
// Create your initial result array
[[DGManager sharedInstance] updateVideoStateWith:info callback:^(NSArray *response) {
// Do whatever work you need to do with the response to modify the result array
[subscriber sendNext:result];
[subscriber sendComplete];
}];
} error:^(NSError* error) {
[subscriber sendError:error];
]];
return nil;
}];
}
注意:如果您在从端点 NSString 映射时返回 RACSignal*,您需要 flattenMap
而不是 map
,flattenMap 会将返回到它发出的值。
-(RACSignal*)finalPackage {
RACSignal *endPoint = [[DGConfiguration sharedInstance].apiConfiguration
urlTemplate:DGAPIUrlLocalWatchList];` // 1.
return [[endPointRequestSignal map:^id(NSString *endPoint) { // 2.
return service([NSURL URLWithString: endPoint]);
}].flatten map:^id(NSArray *episodes) { // 3.
NSMutableArray *info= [NSMutableArray array];
__block NSArray *result=@[@(9)]; // test value is 9, result will be updated during callback block
[episodes enumerateObjectsUsingBlock:^(NSDictionary *item, NSUInteger idx, BOOL *stop) {
[info addObject:@{@"id":item[@"id"],@"links":item[@"links"]}];
}];
[[DGManager sharedInstance] updateVideoStateWith:info callback:^(NSArray *response) { // 4.
dispatch_async(dispatch_get_main_queue(), ^{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
result = [[response sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]] copy];
});
}];
return [RACSignal return:result]; // 5.
}].flatten;
}
让我解释一下我想做什么。
- 我通过
endPoint
信号 包裹端点 url
- 使用
map
提取 url 并执行服务调用 (service([NSURL URLWithString: endPoint])
) - 使用
map
从步骤 2 中提取信息并创建info
数据 - 使用回调
updateVideoStateWith
- Return 包含
result
的信号
最终,当我订阅finalPackage
信号时,return初始化为9
。我意识到updateVideoStateWith
回调需要时间return 结果。
我的问题是如何强制 return [RACSignal return:result]
等待数据从回调块更新。我确实尝试过 takeUntilBlock 但不确定如何使用它。我也考虑过使用 switchToLatest 但还是不行。
交叉发布我在 GitHub 问题中的回答:
- (RACSignal*)finalPackage {
return [RACSignal createSignal:^(id<RACSubscriber> subscriber) {
RACSignal *endPointSignal = [[DGConfiguration sharedInstance].apiConfiguration urlTemplate:DGAPIUrlLocalWatchList];
[[endPointSignal map:^id(NSString *endPoint) {
// map your endpoints to episodes and return the array of episodes
}] subscribeNext:^(NSArray* episodes) {
// Create your initial result array
[[DGManager sharedInstance] updateVideoStateWith:info callback:^(NSArray *response) {
// Do whatever work you need to do with the response to modify the result array
[subscriber sendNext:result];
[subscriber sendComplete];
}];
} error:^(NSError* error) {
[subscriber sendError:error];
]];
return nil;
}];
}
注意:如果您在从端点 NSString 映射时返回 RACSignal*,您需要 flattenMap
而不是 map
,flattenMap 会将返回到它发出的值。