Hey Devs 👋
We’re back with another weekly RxJS exploration — and this time, we’re diving into an interesting and less commonly used concept: AsyncSubject.
🔍 What is an AsyncSubject?
Unlike other types of Subjects in RxJS, an AsyncSubject emits only the last value to its subscribers — and only when the subject completes.
Still confused? Don’t worry — let’s break it down step by step.
🧪 Basic Syntax
const subject = new AsyncSubject();
🧰 Use Case Example in Angular
In this example, we'll bind a value from a textarea, send it to the AsyncSubject, and subscribe using the Angular async pipe.
🧩 HTML
<h3>AsyncSubject</h3>
<div class="text-wrapper">
<div class="text">
<textarea
class="textarea-modern"
[(ngModel)]="asyncSubjectText"
name="asyncSubject"
id="asyncSubject"
></textarea>
<div class="btn-container">
<button class="btn-ghost" (click)="sendAsyncSubject()">Send</button>
<button class="btn-ghost" (click)="completeAsyncSubject()">Complete</button>
<button class="btn-ghost" (click)="addAsyncSubject()">Add</button>
</div>
</div>
<div class="example">
<p>User Input:</p>
@for (data of asyncSubjectData(); track $index) {
<div class="card">
<div class="index">{{$index}}</div>
<div class="data">{{data | json}}</div>
</div>
}
<p>AsyncSubject Value:</p>
@for (item of asyncSubjectArray(); track $index) {
@let data = asyncSubject | async;
<div class="card">
<div class="index">{{$index}}</div>
<div class="data">{{data | json}}</div>
</div>
}
</div>
</div>
🧠 TypeScript
import { Component, model, OnInit, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AsyncSubject } from 'rxjs';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-rxjs-operator',
imports: [CommonModule, FormsModule],
templateUrl: './rxjs-operator.html',
styleUrl: './rxjs-operator.scss',
})
export class RxjsOperator implements OnInit {
asyncSubject = new AsyncSubject();
asyncSubjectArray = signal<number[]>([0]);
asyncSubjectText = model<string>('');
asyncSubjectData = signal<string[]>([]);
ngOnInit(): void {}
addAsyncSubject() {
this.asyncSubjectArray.update((prev) => [...prev, 1]);
}
sendAsyncSubject() {
this.asyncSubjectData.update((prev) => [...prev, this.asyncSubjectText()]);
this.asyncSubject.next(this.asyncSubjectText());
}
completeAsyncSubject() {
this.asyncSubject.complete();
}
}
✅ Case 1: Initial State
Just like a regular Subject, AsyncSubject has no initial value. Before you send any data, subscribers receive null.
✅ Case 2: Sending Multiple Values
When sending multiple values through AsyncSubject, only the last value before calling .complete() is emitted to subscribers.
We print both the user’s input and what the AsyncSubject actually emits.
📌 Note: Once .complete() is called, no further values are accepted or emitted.
✅ Case 3: Multiple Subscribers
You can have multiple subscribers at different times. If the AsyncSubject is already completed, any new subscriber will immediately receive the last emitted value.
🧬 Under the Hood
Internally, AsyncSubject extends Subject, but overrides the next() and complete() methods.
export class AsyncSubject<T> extends Subject<T> {
next(value: T): void {
if (!this._closed) {
this._value = value;
this._hasValue = true;
}
}
complete(): void {
const { _hasValue, _value, _isComplete } = this;
if (!_isComplete) {
this._isComplete = true;
_hasValue && super.next(_value!);
super.complete();
}
}
}
When to Use AsyncSubject?
AsyncSubject is ideal when:
- You need to emit only the final result after some operation is done.
- You want to replicate Promise-like behavior using Observables.
- You want subscribers to get only the final output, no matter when they subscribe.
🏁 Conclusion
AsyncSubject is powerful in scenarios where you care only about the final emitted value. Though used rarely, it’s an excellent fit for promise-style observables or final-state-only data sharing.
💬 Got questions or use cases you want to share? Drop a comment below! Let's discuss more Javascript magic. ✨
✍️ Author: Vetriselvan
👨💻 Frontend Developer | 💡 Code Enthusiast | 📚 Lifelong Learner | ✍️ Tech Blogger | 🌍 Freelance Developer


Top comments (0)