observable
observable copied to clipboard
Promises are inferior to observables for `.every` because the result may be known synchronously but is not readable synchronously
Promise-returning APIs are strictly inferior to observable-returning APIs
A promise cannot be synchronously read. An observable can synchronously fire events. So it's quite unfortunate that you will be unable to read the value of .every (et al) immediately, even if the value is known to be false:
const myObservable = new Observable(subscriber => subscriber.next(123))
myObservable.every(x => x !== 42).then(() => console.log('then callback'))
// yes, this isn't equivalent. I'm being quite lazy
let hasFired = false;
myObservable.subscribe({ next: x => if (x !== 42 && !hasFired) { hasFired = true; console.log('subscribe callback') } })
subscribe callback will be logged during the same tick, and then callback subsequently. This seems like a huge disincentive to using the promise-returning methods like .every, and a strong incentive to use the superior userland variant.
Is this a real-world concern?
- This pattern (synchronously reading the result of an observable) is used in Relay, and I'm sure elsewhere.
- In React, if you are reading data from a promise that has already resolved, you have to: throw (i.e. interrupt rendering), store the promise value elsewhere where it can be read synchronously, and re-render. That's a lot! Instead, if one used an observable, one could read the value synchronously and avoid that overhead.
An alternative
If the fact that observables are meant to be able to serve more than one event a reason to use a less performant API, I would suggest introducing a new class (OneShotObservable?) which will call next at most once, and can call it synchronously.
There's some overlap with #20.