我有一组实体,我想对实体执行异步操作。这些操作应该与数组中的实体链接并以相同的顺序运行。我是 RAC 的新手。如何在 RAC 中做到这一点?
问问题
4916 次
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 回答