Как я могу подписаться на одноразовый сигнал и условно инициировать вторичный сигнал без двойного срабатывания исходного сигнала?
Я хотел бы подписаться на сигнал одной веб-операции и заставить ее условно инициировать вторичную веб-операцию.
Код, который я собрал, выглядит примерно так:
RACSignal *asyncWebAPI = [self asyncWebAPI];
@weakify(self)
[asyncWebAPI
subscribeNext:^(RACTuple *tuple) {
@strongify(self)
NSArray *foo = tuple.first;
[self.bar addObjects:foo];
self.baz = tuple.second;
}
error:^(NSError *error) {
}];
[[[[asyncWebAPI
map:^id(RACTuple *tuple) {
NSArray *foo = tuple.first;
// Return an array of objects where we want anotherAsyncWebAPI to work with as input
NSMutableArray *qux = [NSMutableArray array];
for (id element in foo) {
if (element.someProperty == -1) {
[qux addObject:element];
}
}
return [NSArray arrayWithArray:qux];
}]
filter:^BOOL(NSArray *qux) {
// We really only want anotherAsyncWebAPI to perform if the array has elements in it
return (qux.count != 0);
}]
flattenMap:^RACStream *(NSArray *qux) {
@strongify(self)
return [self anotherAsyncWebAPI:qux];
}]
subscribeNext:^(id x) {
// subscribe and deal with anotherAsyncWebAPI
}];
Выше, однако, заставляет asyncWebAPI становиться горячим сигналом дважды.
Как я могу сохранить вышесказанное как два отдельных конвейера, в отличие от одного беглого конвейера, при достижении условного запуска второй веб-операции?
1 ответ
Для случаев, когда код находится в той же области, вы можете сделать это с помощью RACSubject
поделиться сигналом, или с помощью RACMulticastConnection
,
Используя RACSubject
это будет выглядеть так:
RACSubject *webAPISubject = [RACSubject subject];
[webAPISubject subscribeNext:^(RACTuple *tuple) {
@strongify(self)
NSArray *foo = tuple.first;
[self.bar addObjects:foo];
self.baz = tuple.second;
}];
[[[[webAPISubject
map:^id(RACTuple *tuple) { /* ... */ }]
filter:^BOOL(NSArray *qux) { /* ... */ }]
flattenMap:^(NSArray *qux) { /* ... */ }]
subscribeNext:^(id x) { /* ... */ }];
// Open the gates to let the data flow through the above subscriptions
[[self asyncWebAPI] subscribe:webAPISubject];
В качестве альтернативы, используя RACMulticastConnection
код будет выглядеть примерно так же, как указано выше. Основным отличием является начало и конец.
RACMulticastConnection *webAPIConnection = [[self asyncWebAPI] publish];
затем замените ссылки на asyncWebAPI
в вашем образце с webAPIConnection.signal
, Наконец, в конце позвоните:
// Open the gates to let the data flow through
[webAPIConnection connect];
Технически, я не думаю, что есть большая разница (RACMulticastConnection
использования RACSubject
за кулисами), а это значит, что дело вкуса. Лично я предпочитаю использование предмета, я считаю его более простым.