在此示例中,为什么在CombineLatest和merge之后再次触发初始流?

时间:2018-10-09 09:59:41

标签: rxjs rxjs5

查看下面的摘录:

  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)。存在refreshStreamrandomUserStream以便重用requestStream中的其他97个用户。问题是,当我运行上面的代码时,我仍然在控制台performing request to: ...上看到3次。

我注意到这是在最后一个流中添加merge方法之后发生的,但是,我不确定为什么会发生这种情况。

我的理解是:当我merge refreshStreamrandomUserStream发出新项目时,请点击refresh按钮,然后点击{对于稍后的{1}}按钮,将解析并向前传递remove上先前发出的数组,而不是单击本身。这不应重新触发requestStream

有人可以帮助我了解为什么会发生这种情况以及如何处理这种情况吗? -这样一来,我可以在首次调用期间从API返回的用户中获取最大的收益?

1 个答案:

答案 0 :(得分:1)

之所以会这样,是因为您实际上有三个performance: { hints: false } 的订阅。您对这三个互动方式的直觉是正确的,但是,因为您的requestStream可观察性很差,所以每次订阅时都会创建一个新的流。

这不一定很明显,因为仅明确地进行了一个订阅,但是每次将requestStream传递给requestStream时,它将最终创建一个新的订阅,从而开始一个新的流,在这种情况下会调用您的基础API。

如果您不希望发生这种情况,建议您使用combineLatest之类的多播运算符

因此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