You might have noticed that all reactive abstractions we have encountered in this book have a few things in common. For one, they work as "container-like" abstractions:
Futures encapsulate a computation that eventually yields a single value
Observables encapsulate computations that can yield multiple values over time in the shape of a stream
Channels encapsulate values pushed to them and can have them popped from it, working as a concurrent queue through which concurrent processes communicate
Then, once we have this "container," we can operate on it in a number of ways, which are very similar across the different abstractions and frameworks: we can filter
the values contained in them, transform them using map
, combine abstractions of the same type using bind
/flatMap
/selectMany
, execute multiple computations in parallel, aggregate the results using sequence
, and much more.
As such, even though the abstractions and their underlying workings are fundamentally different, it still feels they belong to some type of higher-level abstractions.
In this appendix, we will explore what these higher-level abstractions are, the relationship between them, and how we can take advantage of them in our projects.