WICG / observable

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

Do we really need observables in the platform? #41

Closed artalar closed 1 year ago

artalar commented 1 year ago

Hi there! The title is a little rude, but the question is important. Of course Observable is a common techic, but there are few problems for a proposal. When we work in the context of a worldwide platform without possibilities for breaking changes, we should choose new primitives very carefully. I think "Observable" is not worth it.

The profits of observables:

The difficulties of observables:

The last topic is the most confusing for me personally. I have been researching and developing reactive primitives for more than 5 years already, and what I'm sure of is that we still don't know enough about it.

A lot of problems developers encounter are due to the glitch problem. There are many ways to handle it, but there is no universal solution. Here is a brief overview from "Angular Reactivity with Signals" topic:

reactive algorithms

Even Angular recently moved a part of "reactive work" from observables to the new (or old?) signals. Is this the beginning or the end of the journey?

A good reactive platform should cover a lot of cases: glitches, priority scheduling, contextual execution, aborting, and error handling. And there are no standards in these questions.

So, okay, we will add the current proposal to the platform. Will it still be relevant after 5 or 10 years?

IMHO we are still not ready for this.

Jamesernator commented 1 year ago
  • Totally new semantics, which are hard for newbies.

Honestly I'm not convinced this is the case, I learnt about observables fairly early on in learning programming and even then they seemed a cleaner solution to the mess that is (still) event listeners.

We already have callbacks, promises, async/await

Promises and async/await are arguably redundant with callbacks, yet they were hugely successful and are now basically used everywhere possible in the web platform. Why? Because they are just far easier to structure than callbacks ever were. Observables are basically meant to ease the same usability problems events have long suffered, like the explainer is mostly even mostly about integration with event target.

I have been researching and developing reactive primitives for more than 5 years already, and what I'm sure of is that we still don't know enough about it.

I personally don't see Observables as some end-all solution to state management or "reactive programming" like rxjs's naming would imply. Honestly I think just being able to have a better wrapper than the awful .addEventListener API is by itself enough of a value proposition for inclusion on the web.

artalar commented 1 year ago

@Jamesernator, thank you for the answer. I appreciate your positive outlook on this API, as I also see the same benefits. Especially as another author of a reactive library, I want this to become a part of the native APIs! However, we should consider all the facts regarding the new API. It will certainly be used not only for DOM events but also extensively in various other tasks of regular development. So, should this simple API, which we couldn't revert in the future, be a part of the platform? Or would it be better to be just a 1KB library with semantic version control?

nin-jin commented 1 year ago

I would suggest introducing 2 low level abstractions: Publisher and Subscriber, where the second has an API for automatic/manual (un)subscriptions. This will allow us to implement any reactivity models.

benlesh commented 1 year ago

I think you're conflating this proposal with RxJS and Angular. Signals are great, but the use cases don't line up:

Signals have no real use in the web platform or DOM APIs.

That said, Observables and/or the observable contract can be used to create a Signal. Any given signal is effectively an Observable<void> that notifies that the value has changed, and then a getter() that will get the updated value.

I know the Angular community is very excited about signals. I know there's a growing number of people out there that have formed strong opinions about how they might relate to observables, and I admire the enthusiasm here... but ultimately this issue has little to do with what we're trying to add here.


To this point:

We already have callbacks, promises, async/await

This is true, however callbacks provide none of the guarantees around teardown that observables do. They also don't provide a uniform interface for defining a set of events. Promises really only suit a guaranteed single value (or error), and are non-cancellable. They're great for async/await semantics and for HTTP calls you don't want to cancel. The same issues that Promise has somewhat plague AsyncIterator because of the added complexities around "pull then push" and the fact the push can't be cancelled.

Observable is a very primitive type, literally the "dual of iterable" which is something we already have in the language.

benlesh commented 1 year ago

Given that goal of this proposal is the improvement of EventTarget by exposing sets of events with Observable; I think this issue can be closed as out of scope. Signals (and computed signals) are great for rendered state management, but not for exposing access to raw events.

@artalar I'd recommend filing a proposal with the TC39, or filing and issue with the WHATWG/DOM repository proposing your API. I'd be sure to include how you think Signals would best be used in the DOM.

https://github.com/whatwg/dom/issues/new

artalar commented 1 year ago

@benlesh, I don't think signals are the main point heavily related to the proposal. They are just an example of "thinking differently." The question remains: Why should the current interface of observables be a part of the standard?

I'm very involved in the "teardown" topic and think this is an important feature. However, there could be other APIs to achieve this feature, such as generators. Personally, I have developed a library that has the same feature with manual context propagation (using the first argument). Here's an example: https://gist.github.com/artalar/085821ff3859828784efbdc6a810394a. Code without observables pipe/chain style may look a little more complex, but it is also much more flexible and easier to debug!

But the most important thing is that AsyncContext is coming, and it could "turn on" teardown management for almost all kinds of APIs, which makes Observables completely unnecessary.