Issue
There are several resources out there (like this one) that define what a "finite" observable is (an observable that eventually stops emitting values). From what I’ve read, it is generally accepted that finite observables do not need to be unsubscribed from.
Is there anything that needs to be done to explicitly define an Observable as "finite"? This article shows how the Angular HttpClient calls complete()
on its Observer
is something that forces its observers to unsubscribe. Is this what makes it "finite"? Or can an observable be finite just by its nature, without explicitly calling complete()
? If so, is it safe to NOT unsubscribe from an observable that is finite by nature?
Solution
Yes and No.
Some observables are finite by construction. This includes all Promises, for example. It also includes
const someArray = [/* array contents */]
from(someArray).subscribe({
next: console.log, // Log emissions
error: _ => {}, // We could ignore errorsby omitting this line, but hey
complete: () => console.log("This observable completed");
});
After the contents of the array are logged, this observable will complete. By construction.
Here’s a simplified version of from
that doesn’t complete
function endlessFrom(array) {
return new Observable(observer => {
array.forEach(observer.next.bind(observer))
// observer.complete(); <- Oh no! ;)
return {
unsubscribe: () => {} // Do nothing
}
})
}
const someArray = [/* array contents */]
endlessFrom(someArray).subscribe({
next: console.log, // Log emissions
error: _ => {}, // We could ignore errorsby omitting this line, but hey
complete: () => console.log("This observable completed");
});
If you run this, you’ll see that "This observable completed"
is never logged. Always, a finite observable will call its observer’s complete
or error
callback explicitly. There are no observables that complete via any library magic of any sort.
That being said, many operators do that work for you. RxJS#from
constructs Promises and Arrays are finite, but you can make any source finite with (for example) take
, takeWhile
, ect.
But Really: No
There’s no runtime flag or property that can make an observable finite. The only way is for that Observable to emit an error
or complete
. This makes sense. Even if you could tag an observable as being finite, what mechanism could an observer use to know when an observable had fulfilled its obligation to complete?