查看下面的摘录:
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
以便重用requestStream
中的其他97个用户。问题是,当我运行上面的代码时,我仍然在控制台performing request to: ...
上看到3次。
我注意到这是在最后一个流中添加merge
方法之后发生的,但是,我不确定为什么会发生这种情况。
我的理解是:当我merge
refreshStream
和randomUserStream
发出新项目时,请点击refresh
按钮,然后点击{对于稍后的{1}}按钮,将解析并向前传递remove
上先前发出的数组,而不是单击本身。这不应重新触发requestStream
。
有人可以帮助我了解为什么会发生这种情况以及如何处理这种情况吗? -这样一来,我可以在首次调用期间从API返回的用户中获取最大的收益?
答案 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