什么是创建信号信号以组合信号并在完成或错误时完成的首选方法?

Jon*_*Jon 5 objective-c reactive-cocoa

我有通过NSNotificationCenter的成功通知和失败通知.我写了一些测试来弄清楚如何将来自这两个通知的信号组合成一个信号,该信号在失败通知命中时提供错误,然后在成功通知命中时提供完成.

目前,完整的块不会被击中,接下来会出现错误.

另外,第二个红利问题:为什么没有@ [errorNotification,completeNotification] .rac_sequence.signal与下面的信号创建信号做同样的事情?

码:

-(void)test_flatten_signal_of_signals_and_convert_notification_to_error{
    RACSignal *errorNotification = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"TEST_FAILURE" object:nil] take:1];


    errorNotification = [errorNotification flattenMap:^(NSNotification *notification){
        return [RACSignal error:[NSError errorWithDomain:@"RAC_TEST" code:1 userInfo:nil]];
    }];

    RACSubject *completeNotification = [RACSubject subject];

    RACSignal *signalOfSignals = [[RACSignal
                                   createSignal:^RACDisposable *(id<RACSubscriber> subscriber){
                                       [subscriber sendNext:errorNotification];
                                       [subscriber sendNext:completeNotification];
                                       [subscriber sendCompleted];
                                       return nil;
                                   }]
                                  flatten];


    __block BOOL hitCompleted = NO;

    [signalOfSignals
     subscribeNext:^(id val){
         STFail(nil);
     }
     error:^(NSError *err){
         hitCompleted = YES;
     }
     completed:^{
         STFail(nil);
     }];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"TEST" object:self];

    STAssertTrue(hitCompleted, nil);
}

-(void)test_flatten_signal_of_signals_and_hits_next_complete_on_notification{
    RACSubject *errorNotification = [RACSubject subject];

    RACSignal *completeNotification = [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"TEST_SUCESS" object:nil] take:1];

    RACSignal *signalOfSignals = [[RACSignal
                                   createSignal:^RACDisposable *(id<RACSubscriber> subscriber){
                                       [subscriber sendNext:errorNotification];
                                       [subscriber sendNext:completeNotification];
                                       [subscriber sendCompleted];
                                       return nil;
                                   }]
                                  flatten];


    __block BOOL hitCompleted = NO;
    __block BOOL hitNext = NO;
    [signalOfSignals
     subscribeNext:^(id val){
         hitNext = YES;
     }
     error:^(NSError *err){
         STFail(nil);
     }
     completed:^{
         hitCompleted = YES;
     }];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"TEST_SUCCESS" object:self];

    STAssertTrue(hitCompleted, nil);
    STAssertTrue(hitNext, nil);
}
Run Code Online (Sandbox Code Playgroud)

Jus*_*ers 11

您可以使用内置运算符执行此操作:

RACSignal *successNotification = [[NSNotificationCenter.defaultCenter
    rac_addObserverForName:SuccessNotification object:nil]
    take:1];

RACSignal *errorNotification = [[NSNotificationCenter.defaultCenter
    rac_addObserverForName:FailureNotification object:nil]
    flattenMap:^(NSNotification *notification) {
        // Convert to a meaningful error somehow.
        NSError *error = …;

        return [RACSignal error:error];
    }];

RACSignal *signal = [RACSignal merge:@[ successNotification, errorNotification ]];
Run Code Online (Sandbox Code Playgroud)

这将为您处理,更明显地指示每个通知如何映射到值或错误.

为什么不在@ [errorNotification,completeNotification] .rac_sequence.signal做与下面信号创建信号相同的事情?

创建的信号将异步发送其值,与您在示例中创建的信号不同.