我想并行启动多个独立的网络请求,并在所有请求完成时订阅(我不在乎它们是否已完成或错误)。
目前,我使用combineLatest
。因此请求是并行的(如我所愿),但是当信号发送error
时,我在订阅中出错。
我找不到允许我并行启动多个独立请求的运算符,并在完成所有操作后进行监听。
此致
修改
在其他情况下(我需要单独使用信号),我需要订阅错误。所以我仍然需要我的信号才能sendError:
。
我的用例是:
一方面,我有一个可以完全同步的应用程序。这将启动所有独立请求。我需要知道何时完成所有请求才能解除progressHUD。我不在乎我的信号是sendError
还是sendCompleted
。
但另一方面,我有多个按钮,我可以在每个请求中单独重新启动,在这种情况下,我需要告诉用户信号是成功还是失败。
答案 0 :(得分:1)
我使用catch
运算符想出了答案:
我将catch
RAC运算符添加到我的所有信号中,以便在信号失败时生成新的[RACSignal empty]
:
NSArray* allSignals = @[signal1, signal2, signal3, signal4];
NSMutableArray* optionalSignals = [NSMutableArray array];
for (RACSignal* signal in allSignals) {
RACSignal* catchableSignal = [signal catch:^RACSignal *(NSError *error) {
return [RACSignal empty];
}];
[optionalSignals addObject:catchableSignal];
}
return [RACSignal combineLatest:optionalSignals];
这不会改变我个人信号的性质,我会受益于combineLatest
功能。
修改强>
如果有人有更优雅的RAC方式来处理for ... in循环,我仍然感兴趣。
答案 1 :(得分:1)
您可以使用rac_sequence
和map
代替循环。此外,在您使用catchTo
时,使用catch
的方式与NSArray* allSignals = @[signal1, signal2, signal3, signal4];
RACSequence *optionalSignals = [[allSignals rac_sequence] map:^id(RACSignal *signal) {
return [signal catchTo:[RACSignal empty]];
}];
return [RACSignal combineLatest:optionalSignals];
相同,同时使代码更简洁:
import scala.util.parsing.combinator._
class JSON extends JavaTokenParsers {
def value : Parser[Any] = obj | arr |
stringLiteral |
floatingPointNumber |
"null" | "true" | "false"
def obj : Parser[Any] = "{"~repsep(member, ",")~"}"
def arr : Parser[Any] = "["~repsep(value, ",")~"]"
def member: Parser[Any] = stringLiteral~":"~value
}
答案 2 :(得分:0)
您可以尝试以下代码:
- (void)getAllItemsWithCompletion:(void (^)())completion {
NSArray *signals = [self.allItems.rac_sequence map:^id(Item *item) {
return [[[self getForItemSignal:item] doCompleted:^{
//done
}] doError:^(NSError *error) {
//Change the button title to retry
}];
}].array;
[[RACSignal combineLatest:signals] subscribeCompleted:^{
NSLog(@"All tasks are done");
}];
}
- (RACSignal *)getForItemSignal:(Item *)item {
return [RACSignal startEagerlyWithScheduler:[RACScheduler scheduler] block:^(id<RACSubscriber> subscriber) {
[APIClient getFeeForItemUUID:item.UUID
success:^(Fee *fee) {
[subscriber sendNext:@(fee)];
[subscriber sendCompleted];
}
failure:^(NSError *error) {
[subscriber sendError:error];
[subscriber sendCompleted];
}];
}];
}