Как я могу подписаться на одноразовый сигнал и условно инициировать вторичный сигнал без двойного срабатывания исходного сигнала?

Я хотел бы подписаться на сигнал одной веб-операции и заставить ее условно инициировать вторичную веб-операцию.

Код, который я собрал, выглядит примерно так:

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за кулисами), а это значит, что дело вкуса. Лично я предпочитаю использование предмета, я считаю его более простым.

Другие вопросы по тегам