我有一个实体数组,我想对实体执行异步操作.操作应链接并以与阵列中的实体相同的顺序运行.我是RAC的新手.如何在RAC中做到这一点?
解决方法
首先,您需要一个执行异步操作的包装器方法,它将返回一个信号.假设异步操作操作采用完成块.从它的声音,你不关心值,你想要副作用,在这种情况下信号不发送值,它只完成.
- (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:operation基本上等待上一个操作在开始下一个操作之前完成.
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和非常好记录的标题,这些标题在我刚出现时对我来说非常有价值.