对同一个 Observable 的多个订阅

Multiple subscriptions to same Observable

我在我的应用程序的一个组件中有多个订阅,我可以看到有几个实例在重复订阅同一个可观察对象。

我最近遇到的一个问题是在一个订阅逻辑中为一个控件设置值与另一个逻辑冲突,并且两个订阅都在同一个可观察对象上。我们已经通过添加更具体的条件来避免冲突来解决这个问题,但这让我想知道重复订阅相同的可观察组合真的是一个很好的做法(我假设我们可以只在单个订阅者中编写所有逻辑)?随着应用程序的增长,它会在长期 运行 中导致任何性能问题吗?

    combinelatest(observable1, observable2).pipe(
    tap(() = > {
    // do some logic
    // update Property1 to foo
    })
    ).subscribe();

    combinelatest(observable1, observable2).pipe(
    tap(() = > {
    // do some logic
    })
    ).subscribe();

    combinelatest(observable1, observable2, observable3).pipe(
    tap(() = > {
    // do some logic
    // // update Property1 to foofoo
    })
    ).subscribe();

observable1.pipe(
    tap(() = > {
    // do some logic
    })
    ).subscribe()

非常感谢任何指导。

多次订阅一个 observable 是一种很好的做法。但是您必须记住取消订阅您所做的订阅。当您多次订阅一个 observable 而不是取消订阅时,可能会导致内存泄漏。

多次订阅 share observable 并没有错。然而话虽如此,通常 observable 可以根据意义拆分以供重用,并且每个 observable 的粒度没有固定规则,每个 observable 都应该定义为适合您的应用程序需求

例如,我们有一个获取博客 post 按钮,如果您希望多个组件收听该事件,您可以这样做

const onGetPostClick=fromEvent(button,'click')

那么你想要执行 get post http 调用并且还允许其他组件监听这样的事件。

const onGetPost=onGetPostClick.pipe(mergeMap(e=>fetch()....),share())

如果您只对新闻类别post感兴趣

const onGetNews=onGetPost.pipe(filter(post=>post.cat==='news'))

为每个可观察对象赋予意义,您会发现您的代码更加枯燥和简约

combinelatest(observable1, observable2).pipe(
  tap(() = > {
  // do some logic
  // update Property1 to foo
  })
).subscribe();

这正在改变流经流的数据。这是不好的做法,您不应该改变流中的任何数据。您应该创建新对象而不是改变对象。正确的方法是使用 map 和 return 对象的新实例,而不要理会原始对象。

combinelatest(observable1$, observable2$).pipe(
  map(([data1, data2]) = > {
    return [data1, { ...data2, prop1: 'foo' }];
  })
).subscribe();

在现代 JavaScript 应用程序中,我们不会改变对象,因为它会导致不可预测的副作用。

多个观察者订阅相同的可观察对象并没有错,但任何流经它们的对象都不应该发生变化。