The easiest way to understand it is to think of a Subject
as both a producer and a consumer. It's like an open channel where someone can send a message on one end, and any subscribers will receive it on the other end.
+---------------
Sender | => => => => Subscriber
-----------------------+ +-----------
Message => => => => => => => => => => => Subscriber
-----------------------+ +-----------
| => => => => Subscriber
+---------------
In code terms say you have a service with a subject
class MessageService {
private _messages = new Subject<Message>();
get messages: Observable<Message> {
return this._messages.asObservable();
}
sendMessage(message: Message) {
this._messages.next(message);
}
}
Note the messages
getter returning the Subject as an Observable. This is not required. The Subject
is already an observable, and anybody could subscribe directly to the Subject
. But I think the asObservable
pattern is used as a way to limit what users can do with it, i.e. so users only use it to subscribe to, and not emit to. We save the emitting for the sendMessage
method.
Now with this service in place, we can inject it into different components, and this can be a way for two (or more) arbitrary components to communicate (or just receive arbitrary event notifications).
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's own EventEmitter
is actually a Subject
. When we subscribe to the EventEmitter
, we are subscribing to a Subject
, and when we emit
on the EventEmitter
, we are sending a message through the Subject
for all subscribers.
See also:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…