如何在ReactiveCocoa中的信号序列之间创建延迟?

时间:2013-11-18 16:18:30

标签: cocoa reactive-cocoa

我有三个信号要按顺序进行评估,它们之间有一秒钟的延迟。

这个片段做了我想要的,但它很难看:

RACSignal *first = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"First!");
    [subscriber sendCompleted];
    return nil;
}];

RACSignal *second = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"Second!");
    [subscriber sendCompleted];
    return nil;
}];

RACSignal *third = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"Third!");
    [subscriber sendCompleted];
    return nil;
}];

NSArray *signals = @[first, [[RACSignal empty] delay:1.0f],
                     second, [[RACSignal empty] delay:1.0f],
                     third];

NSLog(@"Starting");
[[[signals rac_sequence].signal concat] subscribeCompleted:^{
    NSLog(@"Done!");
}];

打印出来:

2013-11-18 17:13:35.326 Starting
2013-11-18 17:13:35.327 First!
2013-11-18 17:13:36.328 Second!
2013-11-18 17:13:37.329 Third!
2013-11-18 17:13:37.330 Done!

2 个答案:

答案 0 :(得分:7)

您的代码非常接近。你不需要&#34; spacer&#34;信号,您只需要对第一和第二信号进行-delay:次呼叫。 -concat:将序列化信号的执行,以便每个后续信号仅在其先前信号完成后才开始,-delay:将推迟其信号完成的传递,从而提供所需的延迟随后的信号开始工作。您也不需要跳入RACSequence并退出,因为-concat:可以快速列举信号:

NSLog(@"Starting");
NSArray *signals = @[ [first delay:1.0f], [second delay:1.0f], third ];
[[RACSignal concat:signals] subscribeCompleted:^{
    NSLog(@"Done!");
}];

答案 1 :(得分:2)

我为此创建了一个Swift类别:

extension RACSignal {
    func execute() -> RACDisposable {
        return self.subscribeCompleted { () -> Void in

        }
    }

    func executeWithDelay(interval:NSTimeInterval) -> RACDisposable {
        var signals = [RACSignal.empty().delay(interval), self]
        var delayedSignal = RACSignal.concat(signals)
        return delayedSignal.execute()
    }
}

由此可以延迟执行单个信号:

signal.executeWithDelay(2.0) 

要获取信号的响应,您可以使用do方法(doNext,doError,doCompleted等)订阅