Как ждать, пока задача не будет выполнена, а затем вернуть сигнал реактивного какао
-(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;
}
Позвольте мне объяснить, что я пытаюсь сделать.
- Я оборачиваю URL-адрес конечной точки через
endPoint
сигнал - С помощью
map
извлечь URL и сделать сервисный звонок (service([NSURL URLWithString: endPoint])
) - С помощью
map
извлечь информацию из шага 2 и создатьinfo
данные - Делать
updateVideoStateWith
с обратным вызовом - Вернуть сигнал, который содержит
result
В конце концов, когда я подписываюсь на finalPackage
сигнал, возвращаемое значение является инициализированным значением, которое 9
Я понимаю, что updateVideoStateWith
обратный звонок займет время, чтобы вернуть результат.
Мой вопрос, как я могу заставить return [RACSignal return:result]
дождитесь обновления данных из блока обратного вызова. Я пробовал takeUntilBlock, но не уверен, как его использовать. Я также думаю об использовании switchToLatest, но все еще не повезло.
1 ответ
Перекрестная публикация моего ответа от проблемы 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;
}];
}
Примечание: если вы возвращаете RACSignal* при отображении из строки EndPoint NSString, вы захотите flattenMap
вместо map
, flattenMap сгладит сигнал, который возвращается в значение, которое он излучает.