我和RxJS有点挣扎。我有3个Observables。 First Observable在文档点击时发出单个值,并立即完成(有意)。 Second Observable监听第一个$ Observable并映射这些值。最后,第三个Observable以第一个$发出的最后一个元素结束第二个$ Observable。
通过查看代码来理解它更容易:
const somethingHappened = true;
const first$ = Observable.create(observer => {
document.addEventListener('click', e => {
console.log('document clicked!')
if (somethingHappened) {
observer.next(5)
observer.complete()
} else {
observer.next(5)
}
})
})
const second$ = first$.pipe(
map((a: number) => a * 10),
)
const third$ = second$.pipe(
concat(first$.pipe(last(), map(element => console.log('last element:', element)))),
)
third$.subscribe()
演示:https://stackblitz.com/edit/typescript-apcjsh(点击文档并查看控制台)
实际发生的事情真的很有趣。首次点击文档后,我希望第三个$ observable完成,因此,console.log('last element:', element)
应该触发。相反,只有console.log('document clicked!')
火!
下次点击文档console.log('document clicked!')
后会触发两次console.log('last element:', element)
次。
有人可以向我解释那里发生了什么吗?
答案 0 :(得分:0)
首次点击文档后,我希望
third$
可观察完成
为了third$
完成,second$
和concat()
的所有参数都需要完成。 concat()
的论据:
first$.pipe(last(), map(element => console.log('last element:', element)))
是一个全新的Observable,仅在second$
完成之后才订阅 - 因此您最终会在文档上安装第二个点击处理程序。
如果向Observable函数添加一些日志输出:
const first$ = Observable.create(observer => {
console.log('subscribed', Date.now()); // Add this
document.addEventListener('click', e => {
...
您会看到两个已订阅的''消息。一旦页面加载(在调用$third.subscribe()
之后),再次单击文档后第一次(当concat()
订阅其参数时)。