The short answer is yes. I've elaborated a bit on it in this answer
From my perspective, the magic of RxJS is achieved with linked lists.
Imagine you have something like this:
const src$ = new Observable(subscriber => subscriber.next(1))
const src2$ = src$.pipe(
map(/* ... */),
filter(/* ... */),
takeWhile(/* ... */)
)
An operator is a function which returns another function whose single argument is an Observable<T> and whose return type is an Observable<R>. Sometimes, T and R can be the same(e.g when using filter(), debounceTime()...).
Observable.pipe is the important part here. This method is what creates an observable linked list. The process is detailed in the linked answer, but, briefly, this is what you'd roughly get:
S1 // new Observable(...) - the HEAD node
|
S2 // map() - another observable, whose `.source` is `S1`
|
S3 // filter() - another observable, whose `.source` is `S2`
|
S4 // takeWhile() - another observable, whose `.source` is `S3`
When you subscribe(e.g src2$.subscribe()), a new chain will be created based on the existing one, this time it is the subscribers chain. Basically, a new subscriber will be created from .subscribe(subscriber), which will subscribe to takeWhile observable, which will create a takeWhile subscriber, which will subscribe to filter observable, which will create a filter subscriber, which will subscribe to map observable and so on. Finally, the subscriber from callback from new Observable(subscriber => subscriber.next(...)) will be, in this case, the map subscriber.