-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
On Observables vs Emitters #26
Comments
Related, I think that the current Observable proposal, as it stands could be simplified quite a bit and I filed an issue there as well |
Really appreciate this foreward, the fact that you're conscious of how other people feel and the effort you put in. Since we've spoken in person before, I totally understand how kind you are as a person! I also appreciate the detailed engagement, despite not entirely correctly, charitably or fairly characterising the proposal/effort. In it's current lengthy format, I think it would be fair to say it would be unproductive to attempt to respond to everything line-by-line here, but I propose the following breakdown:
Overall, I think you may be approaching this from the wrong perspective. There's already significant challenges to introducing any primitive here. Given that you've already revisited thinking about how you could change the Observable's proposal now, and it's even more similar to Emitter, it would be great to discuss the similarities beside the differences that remain, see which one's we can narrow done and work together on this proposal. |
I think really I just need to see an open source reference implementation. |
My primary concern: I think having a My secondary concern is that we'll be throwing away more than a decade of knowledge and use around a very primitive type that has been proven useful, in order to standardize something untested that the community has not found use for yet. But again, I'd really like to see an implementation of it. |
@benlesh I agree with a lot of what you said, but unless I haven't understood correctly, I have to disagree with:
If you see this answer I gave on SO about a problem of The error happens because Of course, this is related to an RxJS implementation, and |
That's still related to the subscription. Not the emissions. first, take, takeUntil, et al, all cause teardown. Which travels back up the chain. But that's related to the operator chains and how they subscribe. Setting up an observable subscription to unsubscribe is purely optional. |
I think it's fine to travel up the chain, as long the producer (subject) doesn't fail or something of the sort. That said, it seems that the error is not actually in the (I still think that |
Ahead of reading this: I'd greatly like to apologize from any perceived tone here. It's very hard to criticize someone else's hard work without it sounding a little bad in a few spots. That's really not my intent, so if reading any of this upsets anyone, I'm sorry, that's not my intent.
Responding to some of the claims about Observable
I want to clear up a few of these statements I found in this repo:
True
This is not true. Observables can handle individual and multiple consumers, as a biproduct of closures. Observables are an extremely low-level primitive, like a specialized function. For example:
Now, assuming that we have observable in the language, it's possible to make all of this more ergonomic by having EventTarget, et al, use that observable:
Handling multiple consumers is a compositional feature of Observable. You're not locked into "always multicast" or "always unicast". So the above statement is wrong and should be removed, IMO.
Observables error-handling semantics are not much different than that of Promises. So I think "invent new" needs to be explained here in great detail, or it's really just editorializing. "becomes a barrier/challenge" is also something that needs to be demonstrated and justified, in detail, against the challenges of current, existing types, such as callbacks and promises without editorializing.
To be clear, this is a type that has been in many languages and in JavaScript for more than a decade. The error semantics here are well defined and understood. It's not a new type that was created for a new proposal.
If Emitter is a "lower level abstraction" than Observable, it should lend itself to more use cases than Observable and cover more.
Observable:
Emitter:
While you might be able to create an Observable using functions an Emitter, I'm not sure it's going to be very efficient or useful to do so. However, I'm fully confident that with an Observable primitive in the language, an efficient Emitter library could be created as a third party thing.
This is inaccurate. Basically it is saying "it's not Subject, it's a subject and operators" in RxJS-speak. This totally works in RxJS, and has for 4-5 years now:
... that said, I'm not sure it's a great feature:
next
?)Without a reference implementation, this is tough to say. This "bidirectionality" you're speaking of here is really just the result of composition. Each one must subscribe to the previous. However, outside of the act of subscription, all observation (the important part) is completely unidirectional. So this difference might be a bit of a misnomer, or at least needs clarified (both in terms of what Observable is doing, and in terms of exactly how Emitter is not going to do this.
Again, this is highly editorialized and requires evidence or should be thrown out.
It's a byproduct of the compositional nature of functions more than anything. And a hallmark of the reusability of Observable. I don't see any how any type is going to be reusable without some sort of upward call. If you can compose an Emitter from other Emitters, the new emitter must call
run
(or whatever) on the other Emitters it's consuming. That's the "upwards call" you're claiming doesn't exist. Overall, I think this claim should be removed.Issues with Emitter in general
I touched on a lot of this above. But I'd like to summarize my concerns a bit.
until
is a bit more complex than returning aSubscription
, or even better, passing a cancellation token likeAbortSignal
or the like.until
is a highly polymorphic function that takes anumber
, or afunction
, or aPromise
, or anEmitter
. Nothing else in JS does that, other than something likeArray.from
, which in my opinion is a bit different. Withuntil
, you get different behaviors based on different values passed. While RxJS also does this in a few spots, I don't think RxJS should be in the language either.run
, for example) seems to fly in the face of better function composition proposals like the pipeline operator or bind operator.On the grounds of number 4 alone, I would strongly discourage standardizing this type, until more evidence of its usefulness is available.
At the highest level of this proposal, I'd like to steer clear of the author's feelings on how difficult Observable is to understand in comparison to this new Emitter type. I honestly think they're both hard to understand, however, all evidence is that RxJS, which is a beefy, heavy-handed, kitchen-sink approach to Observable, is something people are catching onto more and more easily, and the popularity is growing rapidly. 12.5M downloads a week on npm, used in several large well-known projects (YouTube, Netflix, Slack, PS4, et al), someone even organized a conference about it. None of that is to say Observable is "better", but it is to say that it's certainly does not seem difficult for a large, and growing, number of people to understand. I taught myself observables, and I've been teaching them to other people, and frankly, I'm not that smart.
The text was updated successfully, but these errors were encountered: