使用主题和可观察对象之间有什么区别?两者分别有什么用途?

时间:2018-08-25 05:31:10

标签: javascript rxjs reactivex

我了解了两种可观察的方法。第一个是主题,像这样:

// 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进行的观察对象之间还有另一个区别

3 个答案:

答案 0 :(得分:4)

一个Subject同时是ObservableObserver。这使它极具诱惑力,因为您获得了对Observer的引用,因此您可以在代码中传递它们并从所需的任何位置发出项目。但是,当您从Observable的声明性定义切换为命令性定义时,这大大增加了代码的易错性。

通常来说,应尽可能使用可观察的创建函数(offromcreate)。我想说大多数情况都可以在没有主题的情况下解决。但是有一个陡峭的学习曲线,因为您必须了解大多数Observable创建函数才能遵循该模式。

对于习惯使用强制性代码(即使用JS之类的脚本语言)进行开发的开发人员来说,主题可能会变得更加自然,因为它类似于回调函数的简单包装对象。也许有人会问,如果没有一个主题,为什么仍然要有一个主题。

根据此article,主题只能在一种情况下使用:

  

在没有任何直接外部源的情况下,强制性地和有状态地生成热点。

简而言之,这意味着:当您没有任何外部源(如Observable,Promise或Event)并且需要从函数内部多播类的状态时,请使用Subject。但是,您不应该将该主题公开给其他人!

我建议您阅读这篇文章,这样可以使事情变得更清楚。

答案 1 :(得分:2)

主题同时实现了Observable和Observer接口。

实现Observable界面意味着,除其他外,您可以subscribe进入主题。

实现Observer界面意味着,除其他外,使用Subject可以调用方法next errorcomplete

在要以编程方式控制该Observable事件流的情况下,您可以使用Subject创建Observables,这就是您提到的管理 C B 。

答案 2 :(得分:1)

SubjectObservable之间的关系如下:

class Observable {}

class Subject extends Observable {}

Subject实现Subscriber接口。因此,您可以将Subject用作SubscriberObservable不能这样使用):

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的补充-允许我们在需要时做更多的事情。