我了解了两种可观察的方法。第一个是主题,像这样:
// file A
const message$ = new Subject();
// file B
message$.subscribe( (message) => console.log(message) );
// file C
message$.next("Hello there!");
这种创建Observable的方法使我能够从文件B到文件C交换数据。
第二种方法是通过Observable类,如下所示:
// file A
const click$ = new Observable( function(observer) {
//Alternatively, I can use Observable.create()
document.addEventListener('click', (e) => observer.next(e));
});
// file B
click$.subscribe( (cl) => console.log(cl) );
我可以在主题方式和可观察方式之间收集的主要区别是,我不确定如何在某个文件C之间与观察者的订户进行某种通信。基本上,click $没有.next()
方法,并且观察者方法位于我们传递给可观察对象的函数中。
除了行为上的差异之外,使用Subject进行的可观察对象与使用Observable进行的观察对象之间还有另一个区别
答案 0 :(得分:4)
一个Subject
同时是Observable
和Observer
。这使它极具诱惑力,因为您获得了对Observer
的引用,因此您可以在代码中传递它们并从所需的任何位置发出项目。但是,当您从Observable的声明性定义切换为命令性定义时,这大大增加了代码的易错性。
通常来说,应尽可能使用可观察的创建函数(of,from,create)。我想说大多数情况都可以在没有主题的情况下解决。但是有一个陡峭的学习曲线,因为您必须了解大多数Observable创建函数才能遵循该模式。
对于习惯使用强制性代码(即使用JS之类的脚本语言)进行开发的开发人员来说,主题可能会变得更加自然,因为它类似于回调函数的简单包装对象。也许有人会问,如果没有一个主题,为什么仍然要有一个主题。
根据此article,主题只能在一种情况下使用:
在没有任何直接外部源的情况下,强制性地和有状态地生成热点。
简而言之,这意味着:当您没有任何外部源(如Observable,Promise或Event)并且需要从函数内部多播类的状态时,请使用Subject。但是,您不应该将该主题公开给其他人!
我建议您阅读这篇文章,这样可以使事情变得更清楚。
答案 1 :(得分:2)
主题同时实现了Observable和Observer接口。
实现Observable界面意味着,除其他外,您可以subscribe
进入主题。
实现Observer界面意味着,除其他外,使用Subject可以调用方法next
error
和complete
。
在要以编程方式控制该Observable事件流的情况下,您可以使用Subject创建Observables,这就是您提到的管理 C 和 B 。
答案 2 :(得分:1)
Subject
和Observable
之间的关系如下:
class Observable {}
class Subject extends Observable {}
Subject
实现Subscriber
接口。因此,您可以将Subject
用作Subscriber
(Observable
不能这样使用):
const subj = new Subject()
observable.subscribe(subj)
Subject
可以通过调用Subscriber
方法来隐藏它的asObservable
接口-将Subject
变成普通的Observable
;
当我的代码将要生成事件时,通常使用Subject
,而当我已经有一些事件源时,则使用Observable
例如,将“主题”用作队列:
const queue = new Subject();
queue.pipe(
concatMap(doStuff)
).subscribe()
queue.next('do this')
queue.next('do that')
或使用Subject作为发信号的信号来停止其他Observable
const stop = new Subject();
someObservable.pipe(
map(x => x + 1)
takeUntil(stop)
)
// somewhere in my code
stop.next()
除了行为上的差异之外,使用Subject进行的可观察对象与使用Observable进行的观察对象之间还有另一个区别
我不会说有区别-更像Subject
是普通Observable
的补充-允许我们在需要时做更多的事情。