Objective c ReactiveCocoa takeUntil和takeWhile不';“不要最后发送”;“下一步”;
考虑以下代码段:Objective c ReactiveCocoa takeUntil和takeWhile不';“不要最后发送”;“下一步”;,objective-c,reactive-programming,reactive-cocoa,Objective C,Reactive Programming,Reactive Cocoa,考虑以下代码段: - (RACSignal *)startRouting { ... } - (RACSignal *)updateRoutingWithSession:(NSString *)session { ... } - (RACSignal *)fetchFlights { return [[self startRouting] flattenMap:^RACStream *(NSString *session) { return [[[[self upda
- (RACSignal *)startRouting {
...
}
- (RACSignal *)updateRoutingWithSession:(NSString *)session {
...
}
- (RACSignal *)fetchFlights {
return [[self startRouting] flattenMap:^RACStream *(NSString *session) {
return [[[[self updateRoutingWithSession:session]
delay:2.0f]
repeat]
takeUntilBlock:^BOOL(RACTuple *operationAndResponse) {
AFHTTPRequestOperation *operation = [operationAndResponse first];
NSDictionary *response = [operationAndResponse second];
return [operation isCancelled] || 100 == [response[kPercentComplete] intValue];
}];
}];
}
这里发生的是startRouting
返回一个RACSignal
,它发送一个会话ID。
updateRoutingWithSession:
返回一个RACSignal
,该信号发送一个NSDictionary
外观,包括PercentComplete
属性。两次投票之间有两秒钟的延迟
fetchFlights
将一直运行,直到updateRoutingWithSession:
的PercentComplete
为100
我这里的问题是,最后一个sendNext:
,其中takentilblock
返回true
,没有到达RACSubscriber
我遗漏了什么?澄清一下:您的问题是触发完成的
下一个没有发送出去takentilblock
将传播nexts,直到谓词为NO.(),因此,不会发送最后一个next
。但是你可以订阅completion
,这种情况应该会发生。我在RX的世界里发现了这一点。这通常通过合并两个信号来解决。在谓词为真之前接受重复源的语句。另一个在谓词为true时跳过
这看起来像这样
BOOL (^finished)(id _) = ^BOOL(id _) {
return predicate; // BOOLean here
}
// You want a multicast signal, because multiple signals will subscribe to the source.
// Multicasting it means that you won't get repeated api-requests, in this case.
RACMulticastConnection *source = [[theSignal repeat] publish];
RACSignal *whileNotDone = [source.signal takeUntilBlock:finished];
RACSignal *whenDone = [[source.signal skipUntilBlock:finished] take:1];
RACSignal *merged = [RACSignal merge:@[whileNotDone, whenDone]];
[source connect]; // Needed for a multicast signal to initiate.
合并的
信号将发送下一个
每个下一个
在源
中,包括最后一个。然后发送完成
RX世界的一些参考资料:
绝对正确。我可以做的是不使用takeUntilBlock,而是将谓词移动到updateRoutingWithSession:中,并且只有sendComplete:一旦PercentComplete为100。但这会破坏updateRoutingWithSession的逻辑流:它不知道高阶函数如何使用它,也就是说,它不知道在服务完成之前轮询服务。@HansSjunnesson我认为@allprog试图指出,您可以在这里使用completed
事件来确定takentilblock:
何时返回NO
。您可以通过-subscribebecomplete:
或类似的运算符来执行此操作。@JustinSpahr Summers True,但completed不会发送任何数据。我对最后一个的内容感兴趣,完成信号发送的值。TakeWhile会抑制上一个下一个的传播。啊,对不起,我不明白那部分。在这种情况下,您可以组合一些其他运算符,如-mapreviouswithstart:combine:
和-materialize
,以保留上一个值,然后将完成本身视为一个值。