Pipe RxJS 可观察到现有主题
Posted
技术标签:
【中文标题】Pipe RxJS 可观察到现有主题【英文标题】:Pipe RxJS observable to existing subject 【发布时间】:2018-07-30 13:03:50 【问题描述】:存在正在使用的主题:
const fooSubject = new BehaviorSubject(null);
还有另一个 observable(本例中的另一个主题):
const barSubject = new Subject();
barSubject.subscribe(
value => fooSubject.next(),
err => fooSubject.error(err),
() => fooSubject.complete()
);
barSubject.next('bar');
代码有效,但看起来很笨拙。
有没有更好的管道(广义上,不一定使用pipe
运算符)barSubject
可观察到fooSubject
?它看起来像是一个可以由库本身处理的操作。
【问题讨论】:
【参考方案1】:由于 Subject 已经是具有 next()
、error()
和 complete()
方法的观察者,您可以将其订阅到任何 Observable:
const fooSubject = new BehaviorSubject(null);
const barSubject = new Subject();
barSubject.subscribe(fooSubject);
barSubject.next('bar');
【讨论】:
谢谢,这就是我的意思。完全忘记了订阅也接受观察者。 有些人可能不清楚,将 Subject 订阅到 Observable 是 Observable.subscribe(Subject),而不是 Subject.subscribe(Observable) 我想一般来说,当barSubject
超出范围时,您应该以某种方式从fooSubject
退订。正确的?但是如果fooSubject
完成,您是否必须取消订阅fooSubject
?【参考方案2】:
关于源 Observable 完成后退订,我一直在使用这段代码。它按预期运行,但我不知道它是否是“反模式”......?
const subscription = this.http.get(url)
.pipe(finalize(() => subscription.unsubscribe()))
.subscribe(this.mySubject$);
编辑:您无需取消订阅 http.get(..)
,因为它是 done automatically。因此,对于上面的代码,正确的形式应该是:
this.http.get(url).subscribe(mySubject$)
编辑 2:上面代码的一个问题是当 http.get 完成时,mySubject$
也将完成。现在,如果你 .subscribe(mySubject$)
或 mySubject$.next(..)
它不会发出值。为避免这种情况并保持mySubject$
热门,请使用以下代码:
this.http.get(url).subscribe(r => this.mySubject$.next(r))
【讨论】:
谢谢,可以这样做,但它确实是一种反模式。有操作员订阅 1 个值,如果在 1 个值之后完成了 observable,则不需要它们 - http 可能会。请注意,问题是关于主题的。 Apols 用于主题污染(谷歌一直把我带回这里)。这会是更好的代码吗?this.http.get(url).pipe(take(1)).subscribe(mySubject$)
在处理 HttpClient 时,我什至需要为取消订阅而烦恼吗?
您不需要取消订阅,例如http.get(..).subscribe()
因为在内部,收到 HTTP 响应后,代码会调用 complete()
,它会自动取消订阅所有订阅者。来源lukaonik.medium.com/…
"这会是更好的代码吗?" - 是的,如果它不是一次性的 observable 会更好(即发出 1 个值并完成,类似于 promise)。如果 http 是 Angular 的 Http
,那么正如文章所说,它是一次性的,因为它不能发出多个值以上是关于Pipe RxJS 可观察到现有主题的主要内容,如果未能解决你的问题,请参考以下文章