Как ждать, пока задача не будет выполнена, а затем вернуть сигнал реактивного какао

-(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;
}

Позвольте мне объяснить, что я пытаюсь сделать.

  1. Я оборачиваю URL-адрес конечной точки через endPoint сигнал
  2. С помощью map извлечь URL и сделать сервисный звонок (service([NSURL URLWithString: endPoint]))
  3. С помощью map извлечь информацию из шага 2 и создать info данные
  4. Делать updateVideoStateWith с обратным вызовом
  5. Вернуть сигнал, который содержит 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 сгладит сигнал, который возвращается в значение, которое он излучает.

Другие вопросы по тегам