什么是Subject?RxJS Subject是一种特殊类型的Observable,允许将值广播到多个观察者。虽然普通的Observables是单播的(每个已订阅的观察者拥有Observable的独立执行),但Subjects是多播的。
它继续给出了示例,但我正在寻找一个基本的ELI5解释。据我理解,它有助于处理和定义序列中的项目。这正确吗?
我认为对我和其他人最有帮助的是看到一个简单的函数,有或没有定义rxJS Subject,以理解为什么它很重要?
谢谢!
什么是Subject?RxJS Subject是一种特殊类型的Observable,允许将值广播到多个观察者。虽然普通的Observables是单播的(每个已订阅的观察者拥有Observable的独立执行),但Subjects是多播的。
它继续给出了示例,但我正在寻找一个基本的ELI5解释。据我理解,它有助于处理和定义序列中的项目。这正确吗?
我认为对我和其他人最有帮助的是看到一个简单的函数,有或没有定义rxJS Subject,以理解为什么它很重要?
谢谢!
理解它最简单的方法是将一个 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
属性返回的是一个 Observable 对象。这不是必需的。因为 Subject
已经是一个 Observable,任何人都可以直接订阅它。但我认为使用 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
,当我们对EventEmitter
进行emit
时,我们正在通过Subject
向所有订阅者发送消息。
当你所编写的代码实际上是产生可观察数据的源头时,Subjects
是非常有用的。你可以轻松地让你的消费者订阅 Subject
,然后调用 next()
函数将数据推入管道。
然而,如果你从其他来源获取数据并仅仅是传递它(可能首先进行转换),那么你最有可能要使用 此处 显示的其中一个创建运算符之一,例如 Rx.Observable.fromEvent
像这样:
var clicks = Rx.Observable.fromEvent(document, 'click');
clicks.subscribe(x => console.log(x));
Subject
虽然有其用途,但有些人认为这是一种将命令式代码强制进入声明式框架的不良迹象。
这里有一个很好的答案,解释了这两种范式的区别。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>