【问题标题】:RxJS - Observable is not emitting value with .next() on first callRxJS - Observable 在第一次调用时没有使用 .next() 发出值
【发布时间】:2018-09-30 08:44:25
【问题描述】:

我在使用 RxJS 时有些吃力。我有 3 个 Observables。 First Observable 在单击文档时发出一个值并立即(有意地)完成。 Second Observable 监听 first$ Observable 并映射这些值。最后,第三个 Observable 将 second$ Observable 与 first$ 发出的最后一个元素连接起来。

看代码更容易理解:

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()

demo:https://stackblitz.com/edit/typescript-apcjsh(点击文档查看控制台)

实际上正在发生的事情真的很有趣。在第一次点击文档后,我希望 third$ observable 完成,因此,console.log('last element:', element) 应该会触发。相反,只有console.log('document clicked!') 会触发!

下次单击文档后,console.log('document clicked!') 会触发两次,console.log('last element:', element) 会触发一次。

谁能给我解释一下那里发生了什么?

【问题讨论】:

    标签: javascript rxjs observable


    【解决方案1】:

    第一次点击文档后,我期待third$ observable 完成

    为了完成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() 订阅其参数时)。

    【讨论】:

      猜你喜欢
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      相关资源
      最近更新 更多