RACCommand单独处理成功完成
RACCommand separate handling of successful completion
我在实现一些简单的逻辑代码时遇到了问题。
简单来说,我想做这样的事情:
Complete command() {
if (error) {
show error alert
}
else {
show "Happy ending" allert
}
}
我知道如何制作第一部分,但第二部分我有问题
我的尝试:
[self.vm.applyCommand.errors subscribeNext:^(id x) {
//Show alert with error
}];
[[[self.vm.applyCommand.executionSignals
map:^(RACSignal *signal) {
return [[signal ignoreValues] materialize];
}]
concat]
subscribeNext:^(RACEvent *event) {
//Show alert with "Happy end"
}];
在这种情况下,一切都按预期工作,直到出现错误。如果出现错误,我会看到 两个警报(一个有错误,另一个有 "Happy end"),但只想要一个有错误。
我知道为什么会这样,
Errors will be automatically caught upon the inner signals ...etc
但我想要一些解决方案来实现理想的行为。
UPD:“...查看 两个警报(一个有错误,另一个有 "Happy end")”
根据 applyCommand
的执行信号的行为方式,有两种可能的方法可以实现您想要的效果。
如果它只发送一个 next
值然后立即完成,您可以简单地使用 switchToLatest
运算符订阅该 next
值并显示带有 [=42= 的警报]:
[[self.command.executionSignals switchToLatest] subscribeNext:^(id x) {
//Show alert with "Happy end"
}];
否则就复杂多了,因为很难区分RACCommand
的执行信号是成功还是失败。如果出错,调用 [[signal ignoreValues] materialize];
时会得到 "completed" RACEvent
,然后命令的 errors
信号将错误作为下一个值发送。
我设法使用命令的 executing
信号做到了,该信号在 之后发送 @NO
errors
信号发送错误。您可以使用 merge
和 combinePreviousWithStart:reduce
运算符来检查命令是否因为发生错误而停止执行:
RACSignal *stoppedExecuting = [[self.vm.applyCommand.executing ignore:@YES] skip:1];
RACSignal *merged = [stoppedExecuting merge:self.vm.applyCommand.errors];
[[[merged combinePreviousWithStart:nil reduce:^id(id previous, id current) {
return @( [previous isKindOfClass:[NSError class]] || [current isKindOfClass:[NSError class]] );
}] filter:^BOOL(NSNumber *errorOccurred) {
return !errorOccurred.boolValue;
}] subscribeNext:^(id x) {
NSLog(@"Happy end!");
}];
这不是一个完美的解决方案,因为它取决于从各种 RACCommand
的信号发送值的顺序,这是一个实现细节,将来可能会更改(它适用于 RAC 2.5)。
我想这个问题可能会用 RAC 3.0 解决,因为它 replaces RACCommand
with Action
,但我还没有尝试过。
我在实现一些简单的逻辑代码时遇到了问题。 简单来说,我想做这样的事情:
Complete command() {
if (error) {
show error alert
}
else {
show "Happy ending" allert
}
}
我知道如何制作第一部分,但第二部分我有问题
我的尝试:
[self.vm.applyCommand.errors subscribeNext:^(id x) {
//Show alert with error
}];
[[[self.vm.applyCommand.executionSignals
map:^(RACSignal *signal) {
return [[signal ignoreValues] materialize];
}]
concat]
subscribeNext:^(RACEvent *event) {
//Show alert with "Happy end"
}];
在这种情况下,一切都按预期工作,直到出现错误。如果出现错误,我会看到 两个警报(一个有错误,另一个有 "Happy end"),但只想要一个有错误。
我知道为什么会这样,
Errors will be automatically caught upon the inner signals ...etc
但我想要一些解决方案来实现理想的行为。
UPD:“...查看 两个警报(一个有错误,另一个有 "Happy end")”
根据 applyCommand
的执行信号的行为方式,有两种可能的方法可以实现您想要的效果。
如果它只发送一个 next
值然后立即完成,您可以简单地使用 switchToLatest
运算符订阅该 next
值并显示带有 [=42= 的警报]:
[[self.command.executionSignals switchToLatest] subscribeNext:^(id x) {
//Show alert with "Happy end"
}];
否则就复杂多了,因为很难区分RACCommand
的执行信号是成功还是失败。如果出错,调用 [[signal ignoreValues] materialize];
时会得到 "completed" RACEvent
,然后命令的 errors
信号将错误作为下一个值发送。
我设法使用命令的 executing
信号做到了,该信号在 之后发送 @NO
errors
信号发送错误。您可以使用 merge
和 combinePreviousWithStart:reduce
运算符来检查命令是否因为发生错误而停止执行:
RACSignal *stoppedExecuting = [[self.vm.applyCommand.executing ignore:@YES] skip:1];
RACSignal *merged = [stoppedExecuting merge:self.vm.applyCommand.errors];
[[[merged combinePreviousWithStart:nil reduce:^id(id previous, id current) {
return @( [previous isKindOfClass:[NSError class]] || [current isKindOfClass:[NSError class]] );
}] filter:^BOOL(NSNumber *errorOccurred) {
return !errorOccurred.boolValue;
}] subscribeNext:^(id x) {
NSLog(@"Happy end!");
}];
这不是一个完美的解决方案,因为它取决于从各种 RACCommand
的信号发送值的顺序,这是一个实现细节,将来可能会更改(它适用于 RAC 2.5)。
我想这个问题可能会用 RAC 3.0 解决,因为它 replaces RACCommand
with Action
,但我还没有尝试过。