RxJS - Observable在第一次调用时没有使用.next()发出值

时间:2018-04-19 18:34:52

标签: javascript rxjs observable

我和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)次。

有人可以向我解释那里发生了什么吗?

1 个答案:

答案 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()订阅其参数时)。