---
title: "Subject, Observable and Observer"
date: "2026-04"
category: "Angular"
tags: ["Angular"]
description: "Over in Observable's pipe I talked about supplying water, but that was passive supply. What if I want to add water partway through and have everyone drinking from it get the new water? Say switching from groundwater to spring water, with that sweet taste (well......)..."
source: "https://enriquemark.com/en/posts/Subject%E3%80%81Observable%E5%92%8CObserver"
---

Over in [Observable's pipe](</en/posts/Observable的pipe>) I talked about supplying water, but that was passive supply. What if I want to add water partway through and have everyone drinking from it get the new water? Say switching from groundwater to spring water, with that sweet taste (well......). That's where you need `Subject`. Though I have to split something off here first, namely `Observable` and `Observer`. Both of them give you a `next` when you use them, and they're easy to mix up. `next` means operating the water tower, and at the same time it means going to the tower to collect water, that is, the publisher defining the data it sends out and the subscriber receiving data.

```ts
// The generic <number> says this stream sends numbers
const observable = new Observable((subscriber: Subscriber<number>) => {
  subscriber.next(1); // the next here is the method Subscriber implements
  subscriber.complete();
});

// subscribe and test
observable.subscribe({
  next: (val) => console.log(val),
  complete: () => console.log('Done')
});
```

`Subscriber<T>` extends the `Observer<T>` interface, and that interface says the three methods `next`, `error` and `complete` all have to be implemented:

```TS
interface Observer<T> {
  next: (value: T) => void;
  error: (err: any) => void;
  complete: () => void;
}
```

And the element passed into `next` was given directly by `subscriber.next(1)` back when we defined `observable`, which is why the downstream `next: (val) => console.log(val)` can get a value, and what it gets is exactly what's in there. Once that's clear, we know why `Subject` is different: it is itself an `Observable`, and an `Observer` at the same time.

```ts
// 1. build a water tower, groundwater by default
const mySubject = new Subject<string>();
// 2. A comes over to collect water
mySubject.subscribe(data => console.log('A 收到:', data));

// 3. pipe the spring water into the tower!
mySubject.next('山泉水'); 
// console prints: A 收到: 山泉水
```

That means what you do with this object isn't only drawing water anymore, you can also decide what water goes in. And once you add it, every consumer after that is affected. So in practice people don't usually expose `Subject` directly, otherwise, with nothing keeping it in check, downstream will change the whole data stream beyond recognition.

`Subject` does have a "multicast" feature though, which means that when it publishes, it calls back `next` on all downstream subscribers (the objects that ran `subscribe`) and pushes the data from `mySubject.next('山泉水')` over to them. Which is to say, if there's an object that hasn't had `subscribe` triggered by then, not only does it not get this value, it doesn't get any of the others either. Like a high-pressure broadcast water pipe: when it comes it all sprays out, and after that the valve shuts and you don't get a drop. The obvious problem this causes can be seen in a scenario like this: an operation under an event-triggered mechanism, where the user clicks and only then does it `subscribe`. Whoever comes late is left empty-handed with nothing at all.

`BehaviorSubject` is what comes in handy here. It's a `Subject` that keeps acting: it doesn't just push spring water to everyone on the first round, it also gives a share to whoever shows up later. You could call it "the eager water giver". Whatever comes up, you ask and he gives, the opposite of `Subject`'s aloof miss-it-and-it's-gone personality. Most of the time in real use it's this one you're using.

But here's the problem. What if someone's mouth is itching for trouble, turns their nose up at spring water and insists on groundwater? The current supply is single, downstream will only ever get spring water, and that's where `ReplaySubject` comes in. If the first two are, one, stateless: `Subject`, come late and you're empty-handed; and one that only has the latest state: `BehaviorSubject`, whenever you come it gives you the latest (spring water); then `ReplaySubject` holds all of the past and present states within a specified range. It lets downstream consumers get the last N pieces of data, so whoever comes to collect water afterwards can get their hands on spring water or groundwater (depending on the range specified when it's called). If you really do like drinking groundwater, just throw the spring water away yourself; or if you want all of it, no harm in drinking it all. Either way the right to dispose of it goes to downstream. The tower only supplies water, it doesn't care what you do with it.

---

**Translation note.** I wrote this in Chinese. This English version is an LLM translation, so the wording is not mine even though the thinking is. Original: [Subject、Observable和Observer](</zh-hant/posts/Subject、Observable和Observer>).
