Chaining asynchronous operations from an array of objects with ReactiveCocoa

百般思念 提交于 2019-12-03 06:18:54

问题


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 array. I'm new to RAC. How to do that in RAC?


回答1:


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.



来源:https://stackoverflow.com/questions/18907682/chaining-asynchronous-operations-from-an-array-of-objects-with-reactivecocoa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!