【问题标题】:What are RxJS Subject's and the benefits of using them?什么是 RxJS 主题以及使用它们的好处?
【发布时间】:2017-02-14 13:34:14
【问题描述】:

我发现rxJS docs 将它们定义为

什么是主题? RxJS Subject 是一种特殊类型的 Observable,它允许将值多播到多个 Observer。普通的 Observable 是单播的(每个订阅的 Observer 都拥有 Observable 的独立执行),而 Subjects 是多播的。

它继续提供示例,但我正在寻找基本的 ELI5 解释。据我了解,它有助于按顺序处理和定义项目。那是对的吗?

我认为,看看一个简单的函数,无论是否定义 rxJS 主题,这对我和其他人来说都是最有帮助的,以了解它为什么重要?

谢谢!

【问题讨论】:

标签: javascript angular typescript rxjs subject


【解决方案1】:

理解它的最简单方法是将Subject 视为生产者消费者。这就像一个开放的频道,有人可以在一端发送消息,而任何订阅者都会在另一端接收。

                                  +---------------
Sender                            | =>  =>  =>  =>  Subscriber
           -----------------------+   +----------- 
Message =>  =>  =>  =>  =>  =>  =>  =>  =>  =>  =>  Subscriber
           -----------------------+   +-----------
                                  | =>  =>  =>  =>  Subscriber
                                  +---------------

用代码术语说你有一个带有主题的服务

class MessageService {
  private _messages = new Subject<Message>();

  get messages: Observable<Message> {
    return this._messages.asObservable();
  }

  sendMessage(message: Message) {
    this._messages.next(message);
  }
}

注意messages getter 将 Subject 作为 Observable 返回。这不是必需的Subject 已经是一个 observable,任何人都可以直接订阅 Subject。但我认为asObservable 模式被用来限制用户可以用它做什么,即用户只使用它订阅,而不是发送 .我们为sendMessage 方法保存发射。

现在有了这个服务,我们可以将它注入到不同的组件中,这可以成为两个(或更多)任意组件进行通信(或只是接收任意事件通知)的一种方式。

class ComponentOne {
  constructor(private messages: MessageService) {}

  onClick() {
    this.messages.sendMessage(new Message(..));
  }
}

class ComponentTwo {
  constructor(private messages: MessageService) {}

  ngOnInit() {
    this.messages.messages.subscribe((message: Message) => {
      this.message = message;
    });
  }
}

Angular 自己的EventEmitter 实际上是一个Subject。当我们订阅EventEmitter 时,我们正在订阅Subject,当我们在EventEmitteremit 时,我们正在通过Subject 向所有订阅者发送消息。

另见:

【讨论】:

    【解决方案2】:

    当您所在的代码实际上是可观察数据的来源时,主题很有用。您可以轻松让您的消费者订阅Subject,然后调用next() 函数将数据推送到管道中。

    但是,如果您从其他来源获取数据并且只是将其传递(可能首先对其进行转换),那么您很可能希望使用 here 所示的创建运算符之一,例如 Rx.Observable.fromEvent @ 987654322@:

    var clicks = Rx.Observable.fromEvent(document, 'click');
    clicks.subscribe(x => console.log(x));
    

    这使您可以停留在函数式范式中,而使用 Subject 虽然有其用途,但有些人认为这是您试图将命令式代码强制转换为声明性框架的气味。

    Here 是一个很好的答案,它解释了两种范式的区别。

    【讨论】:

      【解决方案3】:

      如果你想要最简单的解释...

      Observables 通常是某事的结果。 http 调用的结果,以及你对管道所做的任何事情都会返回一个 observable。

      但是这些东西的来源是什么?有没有想过如何将用户事件与整个 rxjs 事物挂钩?主题的主要特点是您可以在它们上调用 next() 方法。

      在进行响应式编程时,第一步通常是列出您可能拥有的主题。

      例如:假设我们必须制作一个待办事项列表应用程序。 我们的组件中可能会有几个变量:

      public deleteItem$ = Subject<TodoItem> = new Subject();
      public addItem$ = Subject<TodoItem> = new Subject();
      public saveList$ = Subject<TodoItem[]> = new Subject();
      

      在我们的应用程序中,我们将像这样连接它们:

      <button (click)="deleteItem$.next(item)">Delete</button>
      

      使用 rxjs,我们将使用 merge/combineLatest/withLatestFrom 等运算符来处理这些主题并定义我们的应用程序逻辑。

      我看看能不能有时间做一个小例子。

      【讨论】:

        【解决方案4】:

        你可以找到对主题语义的研究here

        我看到的所有回答都是正确的。我将补充一点,subject 一词来自观察者模式(参见https://en.wikipedia.org/wiki/Observer_pattern)。由于这样的主题是一种中继,它在一端接收某些东西,并在其任何一端(订阅)发出它。

        【讨论】:

          猜你喜欢
          • 2014-05-27
          • 2022-08-13
          • 1970-01-01
          • 2011-08-03
          • 2011-07-04
          • 2016-12-18
          • 2017-10-26
          • 1970-01-01
          • 2011-07-09
          相关资源
          最近更新 更多