一个备注无关的实际问题:filter
应该返回一个布尔值是YES
如果元素应该被发送和NO
如果该元素应该被过滤掉。
要实际的问题:
的解决问题的方法是使用takeUntil
。但是,如果您直接将takeUntil
应用于CS2,则一旦CS1发生事件,CS2将作为一个整体取消。
解决方法是使用flatMap
为延迟元素构建新的RACSignal
,然后在该内部信号上使用takeUntil
。
我拆单步入仅仅是为了清楚多个临时信号(我也改变了map
和filter
,所以我可以看得更清楚发生了什么尝试我的例子时,你应该能够轻松地使用你的正确功能有):
RACSignal* CS1 = [self.origin map:^id _Nullable(NSNumber * _Nullable value) {
return value;
}];
RACSignal *filtered = [self.origin filter:^BOOL(NSNumber * _Nullable value) {
return (value.integerValue % 2) == 0;
}];
RACSignal *delayed = [filtered flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// Build a new signal that returns just this one value,
// but delayed and only if no event arrives on CS1
return [[[RACSignal return:value]
delay:3]
takeUntil:CS1];
}];
RACSignal* CS2 = [delayed map:^id _Nullable(NSNumber * _Nullable value) {
return @(-value.integerValue);
}] ;
RACSignal* CS3 = [RACSignal merge:@[CS1, CS2]];
您可以轻松地折叠此回只有两个信号
RACSignal *CS2 = [[[self.origin filter:^BOOL(NSNumber * _Nullable value) {
return (value.integerValue % 2) == 0;
}] flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// Build a new signal that returns just this one value,
// but delayed and only if no event arrives on CS1 before
return [[[RACSignal return:value]
delay:3]
takeUntil:CS1];
}] map:^id _Nullable(NSNumber * _Nullable value) {
return @(-value.integerValue);
}];
我创建a sample project on github来演示解决方案。
非常感谢。这是非常令人印象深刻的答案。我找到了另一个解决方案(CS2返回信号,然后switchToLatest),但它只是丢弃信号,映射块总是处理。你的答案更加优雅和优化。 – Tepmnthar
似乎CS2永远不会触发@MeXx – Tepmnthar
不是吗?我构建了一个小样本应用程序,通过按钮在'origin'上发送值,并且在该示例中工作。也许你可以展示你的用例的更大图片? – MeXx