I have an array of entities and I want to perform asynchronous operations on the entities. The operations should be chained and run in the same order with the entities in the ar
First, you'll need a wrapper method that performs your async operation, which will return a signal. Let's assume the async operation operation takes a completion block. From the sounds of it, you don't care about the values, you want the side effects, in which case the signal does not send values, it only completes.
- (RACSignal *)asyncOperation {
return [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) {
[self asyncOperationWithCompletion:^{
[subscriber sendCompleted];
}];
return nil; // `nil` means there's no way to cancel.
}];
}
EDIT: Thanks to the comment by Justin Spahr-Summers, here is a much simpler approach to chaining the operations:
RACSignal *signal = [RACSignal concat:[array.rac_sequence map:^(id entity) {
return [entity asyncOperation];
}]];
ReactiveCocoa's +concat:
operator takes a collection of signals and subscribes to the signals one at a time, waiting for completion of one signal before subscribing to its successor. Using -rac_sequence
here is for the purpose of mapping the entities to the operation signals.
In this context, the use of +concat:
achieves the same effect as the -then:
chaining from my initial answer below.
With the RAC wrapper, a solution is to start with an empty signal, and build a chain by iterating over the entities and assembling the operations using -then:. The -then:
operation essentially waits for the previous operation to complete before beginning the next.
RACSignal *signal = [RACSignal empty];
for (id entity in array) {
signal = [signal then:^{
return [entity asyncOperation];
}];
}
[signal subscribeCompleted:^{
// At this point, all operations have completed
}];
At this point what you have is:
[[[[RACSignal empty]
then:^{ return [entity1 asyncOperation]; }]
then:^{ return [entity2 asyncOperation]; }]
// ...
then:^{ return [entityN asyncOperation]; }]
ReactiveCocoa has helpful documentation and very well documented headers, both of which were very valuable to me when I was new.