As mentioned in a discussion on this particular thread, the key distinction between Promises and Observables lies in their handling of asynchronous events. Promises are designed for one-time asynchronous tasks that can either succeed or fail, whereas Observables empower developers to create composable streams by applying various operations to streaming data or events. In both cases, when it comes to returning results from either an Observable or a Promise to synchronous code, a callback is required to serve as a data sink, indicating that the two concepts are not mutually exclusive.
Both Observables and Promises offer the convenience of using composable functions to declaratively define operations on asynchronous data streams. However, Observables stand out in allowing the use of a single callback as a sink to feed results back to synchronous code, eliminating the need for nested function calls or recursive function calls typically involved in composing asynchronous operations solely based on callbacks.