一個備註無關的實際問題: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