9

我有一组实体,我想对实体执行异步操作。这些操作应该与数组中的实体链接并以相同的顺序运行。我是 RAC 的新手。如何在 RAC 中做到这一点?

4

1 回答 1

12

首先,您需要一个执行异步操作的包装器方法,该方法将返回一个信号。让我们假设异步操作操作需要一个完成块。从它的声音来看,你不关心值,你想要副作用,在这种情况下,信号不会发送值,它只会完成。

- (RACSignal *)asyncOperation {
    return [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) {
        [self asyncOperationWithCompletion:^{
            [subscriber sendCompleted];
        }];
        return nil; // `nil` means there's no way to cancel.
    }];
}

编辑:感谢 Justin Spahr-Summers 的评论,这里有一个更简单的链接操作的方法:

RACSignal *signal = [RACSignal concat:[array.rac_sequence map:^(id entity) {
    return [entity asyncOperation];
}]];

ReactiveCocoa 的+concat:操作符获取一组信号并一次订阅一个信号,等待一个信号完成后再订阅其后继信号。在这里使用-rac_sequence是为了将实体映射到操作信号。

在这种情况下,使用可以达到与下面我最初答案中的链接+concat:相同的效果。-then:


使用 RAC 包装器,一个解决方案是从一个空信号开始,然后通过迭代实体并使用-then:. 该-then:操作实质上是在开始下一个操作之前等待上一个操作完成。

RACSignal *signal = [RACSignal empty];
for (id entity in array) {
    signal = [signal then:^{
        return [entity asyncOperation];
    }];
}

[signal subscribeCompleted:^{
    // At this point, all operations have completed
}];

此时你拥有的是:

[[[[RACSignal empty]
    then:^{ return [entity1 asyncOperation]; }]
    then:^{ return [entity2 asyncOperation]; }]
    // ...
    then:^{ return [entityN asyncOperation]; }]

ReactiveCocoa 有有用的文档和非常有据可查的标题,当我还是新手时,这两者都对我非常有价值。

于 2013-09-20T03:02:48.853 回答