Почему первоначальный поток снова запускается после объединения и последнего объединения в этом примере? - PullRequest
0 голосов
/ 09 октября 2018

Посмотрите отрывок ниже:

  let requestStream = Rx.Observable
    .of(`${GITHUB_API}?since=${randomNumber()}`)
    .mergeMap(url => {
      console.log(`performing request to: ${url}`)
      return Rx.Observable.from(jQuery.getJSON(url))
    });

  let refreshStream = Rx.Observable.fromEvent(refreshButton, 'click')
    .startWith('click')
    .do(_ => users.empty())
    .combineLatest(requestStream, (_, users) => users.slice(randomNumber(users.length)));

  let randomUserStream = userRemovedStream
    .combineLatest(requestStream, (_, users) => users[randomNumber(users.length)]);

  requestStream
    .merge(refreshStream)
    .flatMap(users => users)
    .merge(randomUserStream)
    .filter(_ => users.children().length < MAX_SUGGESTIONS)
    .do(user => users.append(createItem(user)))
    .mergeMap(user => Rx.Observable.fromEvent($(`#close-${user.login}`), 'click'))
    .map(event => event.target.parentNode)
    .subscribe(user => {
      user.remove();
      userRemovedStream.next('');
    });

requestStream возвращает массив с 100 пользователями, однако я потребляю только три (MAX_SUGGESTIONS) из них на тот момент.refreshStream и randomUserStream существует для повторного использования 97 других пользователей из requestStream.Проблема в том, что когда я запускаю приведенный выше код, я все еще вижу на консоли performing request to: ... три раза.

Я заметил, что это происходит после добавления методов merge в последний поток,Тем не менее, я не уверен, почему это происходит.

Насколько я понимаю: когда я merge refreshStream и randomUserStream, каждый раз, когда испускается новый элемент, нажмите * 1021Кнопка * для первого и нажатие на кнопку remove для последующего, ранее отправленный массив в requestStream будет проанализирован и передан вперед вместо самого клика.Это не должно повторно вызывать requestStream.

Может кто-нибудь помочь мне понять, почему это происходит и как справиться с этой ситуацией?- чтобы я мог извлечь максимум из числа пользователей, уже возвращенных API во время первого вызова?

1 Ответ

0 голосов
/ 09 октября 2018

Это происходит потому, что у вас есть три подписки на requestStream.Ваша интуиция в том, как эти три взаимодействуют, верна, потому что ваша requestStream Observable холодная, она будет создавать новый поток каждый раз, когда есть подписка.

Это не обязательно очевидно, потому что только одна подпискасделано явно, но каждый раз, когда вы передаете requestStream на combineLatest, в конечном итоге создается новая подписка, которая, в свою очередь, запускает новый поток, который в этом случае вызывает ваш базовый API.

Если вы не используетене хочу, чтобы это произошло, я бы предложил вам использовать оператор многоадресной рассылки, например publishLast

, поэтому requestStream станет:

let requestStream = Rx.Observable
    .of(`${GITHUB_API}?since=${randomNumber()}`)
    .mergeMap(url => {
      console.log(`performing request to: ${url}`)
      return Rx.Observable.from(jQuery.getJSON(url))
    })
    .publishLast();

В этом случае requestStream теперь фактическиConnectableObservable так что вам нужно будет также запустить его в какой-то момент, обычно вы будете ждать, пока все ваши подписчики не будут подключены.

/* Rest of you example */
.map(event => event.target.parentNode)
.subscribe(user => {
  user.remove();
  userRemovedStream.next('');
});

requestStream.connect();
...