Skip to content

Promises are inferior to observables for .every because the result may be known synchronously but is not readable synchronously #203

Description

@rbalicki2

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions