Closed alshdavid closed 1 year ago
While the browser has the EventTarget interface, allowing objects to implement the addEventListener method - this interface is lacking on Node
This isn't actually true anymore, Node already ships EventTarget
and it's even already stable.
and further, requires consumers to specify the event name and submit messages through initializing an Event. Great for HTMLElement instances that have several event types (such as click, hover), but less logical for basic streamable data.
Oh there are a million problems with that interface that we (as in "people who care a lot about the web platform") should address (I have a list somewhere I think?) - I don't think it "competes" with observables although observables in the web platform could complement it.
It's my belief that operators should be dropped from the specification as they can be implemented by user-land libraries and seem to serve to distract from the core value of the proposal.
That's such a good idea and people agree on it that it's already the case :] Look at the spec.
I remember sitting down one weekend earlier this year having fun writing operators for the new proposed API, and it was an absolute joy. And if a pipe operator gets approved that allows point free style, I bet such libraries will flourish.
Hi @benjamingr,
I'd be interested understanding your view on why Observable wouldn't "compete" with previous interfaces (EventTarget, EventEmitter). My understanding was that in most cases it would replace those APIs, how do you see it? I guess older APIs would still make sense for low level implementations (like ports of Web APIs in Node.js).
Either way, you seem to know a lot on this proposal. Do you have an idea of if it planned to have it presented for stage 2 any time soon? Nice to see the spec got significantly smaller anyway.
Thanks!
Either way, you seem to know a lot on this proposal. Do you have an idea of if it planned to have it presented for stage 2 any time soon? Nice to see the spec got significantly smaller anyway.
The proposal is mostly blocked on someone putting in the (admittedly large) amount of work in to prepare it and present it. The committee isn't actually opposed to it. To quote a TC39 member I talked to about this last week "TC39 is not opposed to observables, it is more that no one is working on it"
I'd be interested understanding your view on why Observable wouldn't "compete" with previous interfaces (EventTarget, EventEmitter).
EventTarget and EventEmitter are not a part of JavaScript. EventEmitter is a part of Node.js and EventTarget is a part of WHATWG/dom (and also Node.js).
EventTarget/EventEmitter don't actually compose (you can't really easily "map" them) and they're a much higher level abstraction (observables are fundamentally much simpler).
TC39 is not opposed to observables, it is more that no one is working on it
What work would it require?
This proposed version seems to be the minimal viable standard needed for interop in subscribable-things, observable-value, hyperf and others.
@dy I think the first step would be to find someone from TC39 who is willing to sit down with you and enumerate the things needed to move observable forward (show a good DOM interop story, deal with existing concerns, show viability in language APIs, write an explainer on where push is required etc).
Maybe @ljharb would know what would be an appropriate way to reach out to champions?
Posting on https://es.discourse.group is your best bet.
And if a pipe operator gets approved that allows point free style, I bet such libraries will flourish.
This isn't going to happen. I'd love it if it did. But it's thoroughly blocked by influential people.
FYI: There are more Observable-like implementations in the wild:
I've seen other very, very similar types in dozens of lesser known libraries, as well. A WAMP client I've used comes to mind.
Oh, and @alshdavid, what you have above is missing an important aspect of Observable, which is how to finalize what you've set up during subscription. You need to either pass in some sort of token/signal to register finalization on, or you need to allow the user to return a function that will be called during finalization, or something to that effect.
Posted to es.discourse.
One thing is missing here. API must include [Symbol.observable]
for interop:
class Observable<T> {
...
// Returns itself
[Symbol.observable]() : Observable;
...
}
How does this solve the composition problem? https://github.com/tc39/proposal-observable/blob/master/ObservableEventTarget.md#problem-eventtargets-and-promises-are-difficult-to-compose
Closing this as the discussion has been moved here https://es.discourse.group/t/observables/1175/4
Motivation
The motivation behind this proposal is the need for JavaScript to have a formal interface describing streamable types. You can see this in the way
Observable
-like implementations are re-implemented time and time again.While the browser has the
EventTarget
interface, allowing objects to implement theaddEventListener
method - this interface is lacking on Node and further, requires consumers to specify the event name and submit messages through initializing anEvent
. Great forHTMLElement
instances that have several event types (such asclick
,hover
), but less logical for basic streamable data.The Observable specification, much like
Promise
, provides a standardised interface that everyone can target.It's my belief that operators should be dropped from the specification as they can be implemented by user-land libraries and seem to serve to distract from the core value of the proposal.
Lastly, with so many competing implementations, it's much harder to pipe data from one stream into another without hand written adapters bridging the separate stream implementations.
The Whole Thing
Base Type
Implementation via Github gist Example implementation in replit
Usage
Async
Observable
will execute synchronously unless an asynchronous action happens in the execution chain somewhere. Such as afetch
in theObservable
constructor or asetTimeout
in theSubscriber
Errors
If something throws inside an
Observable
setup callback, an error is pushed to subscribers. If the error method is called, an error is pushed to subscribers.Interfaces
What about
Subject
,ReplaySubject
, etc?These are fantastic types that help with the control flow of streamable values, but can all be made from the base
Observable
. class. and should therefore be left to user-land libraries to implementOperators
The use of operators on the
Observable
type reminds me a bit of how libraries like Bluebird had operators onPromise
. Operators being a part of rxjs and rxjs being so popular makes them feel like they are required forObservable
to be useful but it's important to recognise thatObservable
is simple a standard interface to enable the consumption of streamed values. The reactive extensions are there to enhance that behaviour.While operators may be ergonomic, they are not necessary for the handling of streamable data and can be implemented by user libraries
An example of how operators could be used as implemented by a user-land library is as follows:
Conversion to
Promise
Much like the challenges described by the rxjs team on what it even means to convert a stream to a
Promise
, this falls into the domain of user-land libraries.Conclusion
Keeping the API limited in scope allows solving the major issue with streams in JavaScript, a consistent target API.