首页 文章

什么是RxJS主题和使用它们的好处?

提问于
浏览
9

我发现rxJS docs将它们定义为

什么是主题? RxJS主题是一种特殊类型的Observable,允许将值多播到许多观察者 . 虽然普通的Observable是单播的(每个订阅的Observer都拥有Observable的独立执行),但Subject是多播的 .

它继续举例,但我正在寻找一个基本的ELI5解释 . 根据我的理解,它有助于处理和定义序列中的项目 . 那是对的吗?

我认为,对于我和其他人来说,看看一个简单的函数,有没有定义 rxJS Subject 以理解它为什么重要,这将是最有帮助的?

谢谢!

4 回答

  • 6

    理解它的最简单方法是将 Subject 视为 生产环境 者和消费者 . 它就像一个开放的 Channels ,有人可以在一端发送消息,任何订阅者都会在另一端收到消息 .

    +---------------
    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 已经是一个可观察的,任何人都可以直接订阅 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 为所有订阅者发送消息 .

    另见:

  • 1

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

    但是,如果您从其他源获取数据并且只是传递它(可能首先将其转换),那么您很可能想要使用here所示的创建运算符之一,例如 Rx.Observable.fromEvent like so

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

    这允许你保留在功能范例中,而使用 Subject 虽然它有其用途,但有些人认为这是一种气味,你试图强制命令性代码进入声明性框架 .

    Here是一个很好的答案,可以解释两种范式的不同之处 .

  • 0

    你可以找到一个关于主题语义的研究here .

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

  • 15

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

    可观察量通常是某种东西的结果 . 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等运算符来处理这些主题并定义我们的应用程序逻辑 .

    我会看看我是否能找到时间做一个小例子 .

相关问题