我有一组实体,我想对实体执行异步操作。应该链接操作并以与阵列中的实体相同的顺序运行。我是RAC的新手。如何在RAC中做到这一点?
答案 0 :(得分: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有很多有用的documentation和非常好记录的标题,这些标题在我刚出现时对我来说非常有价值。