WICG / observable

Observable API proposal
https://wicg.github.io/observable/
Other
575 stars 14 forks source link

Ability to destructure Subscriber #102

Closed keithamus closed 8 months ago

keithamus commented 8 months ago

Currently in the Chrome implementation the following fails with an Illegal Invocation:

new Observable(({next}) => next(1)).subscribe(console.log)

This seems like a fairly large ergonomic loss. Is this an IDL limitation? Can annotations be added to prevent it?

domenic commented 8 months ago

Sort of. The most natural thing which IDL encourages is the more performant thing, which is using classes with shared methods. As you know, classes with shared methods need their this value, so subscriber.next(foo) cannot be turned into const { next } = subscriber; next(foo);.

It would be possible to write a complex spec that created bound, per-Subscriber versions of these methods. And that would be less performant, since it would need to create and allocate those methods for every Subscriber. (IIUC, there are more Subscribers than Observables, so this is especially bad.)

FWIW, using the per-Promise resolve and reject functions in new Promise((resolve, reject) => { ... }) is a great regret of mine for this reason. In designing streams, I fixed that, so that the stream controllers use controller classes with shared methods. (E.g. ReadableStreamDefaultController.)

I think "fairly large ergonomic loss" is also overstating it;

new Observable(s => s.next(1)).subscribe(console.log)

is actually 5 fewer characters.

keithamus commented 8 months ago

I don't hold particularly strong opinions on this, but felt it part of due diligence to at least mention as it's a common pattern and I imagine would be surprising to some. As you say though, there are arguably more ergonomic variants and if enabling this feature sacrifices performance that does sound undesirable.

Thanks for the explanation!