-
Notifications
You must be signed in to change notification settings - Fork 231
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
Implement [Symbol.observable] for ES7 interop compliance #160
Comments
Hey @Blesh, thanks for the update. On a quick skim, this sounds good. I'll take a closer look later this week. |
👍 |
Hey @Blesh, reading @zenparsing's repo, it looks like Can you offer an insight into what's going on there? Am I missing something? Thanks for any info as I start to work on this :) |
I see there is quite a bit of discussion in tc39/proposal-observable#48. It seems like returning a function is still more "official", so I'll go with that for now. It's not hard to switch if there is a change. |
@Blesh Is there any information on the synchronous vs. asynchronous delivery of the first event after subscribing? IOW, is an observable allowed to call |
Initial strawman: https://github.com/cujojs/most/tree/add-es7-observable-160 Would love to get some feedback from @davidchase as well. |
@briancavalier, yes subscription is synchronous. I doubt that returning a function from subscribe will hold water. But RxJS can handle either. I don't plan I returning anything but an object with an unsubscribe function right now. I can change that for interop, but I think it's wrong for the type. Cc @zenparsing |
@briancavalier 👍 seems straightforward to me... I am curious to see what they do with the Personally when using other |
@Blesh @zenparsing Hrm, that seems unfortunate. I'd be interested to hear the reasoning behind the decision.
@davidchase This is a great point, and personally, I agree. I think imperative unsubscribe is a foot gun for app devs. I'd much rather see RP implementors promote declarative APIs to devs. That said, imperative unsub is probably a necessity for implementation interop. So, I can see it being a part of an interop spec. It exists internally in most.js because it has to, but this is really the first time it's exposed. |
definitely understand that as well the need for it in
I do as well, especially when the allow for a more |
The reason for synchronous subscription was so it could model DOM events, which can be completely synchronous. |
Hmm, maybe we're talking about different things. I'll try to differentiate based on what I think you're saying (and I could be misunderstanding!):
AFAIK, like promises, DOM events do not allow 2. No DOM event will ever invoke a callback before the associated call to node.addEventListener('<any event>', handleEvent, false);
So, it seems to me that there's precedent in the DOM and promises for not allowing Is there a discussion thread you can point me to on this? I'm happy to do background reading to try to understand. |
Correct, but you can trigger synchronously immediately after addEventListener returns.
I don't see how there's a precedent that relates to Observable. They're different types with different purposes. Here's all of it in a nutshell:
On 1 above: var subscription = Observable.fromEvent(button, 'foo').subscribe(::console.log(x));
button.dispatchEvent(new Event('foo')); // completely synchronous to the subscription above. On 2 above... imagine a range to 1,000,000 or something like that. If |
Yep. That's why I was using the terminology "subscribe.next must not be called before subscribe() returns". We're saying the same thing re: DOM events, I believe.
It relates because both have the potential of unleashing zalgo.
Ah, thanks, I understand the concern here now. This is an interesting tradeoff vs zalgo. I can see for cold observables, this could be important to prevent buffering. For hot observables, I'm having trouble coming up with a realistic case where this would actually happen. Do you have an example handy? I'll think about it more. |
I just added @Blesh I updated the branch to use a subscription object with an unsubscribe method, rather than a closure. Either way seems ok to me. The closure is certainly nice for callers, but if there's concern about creating large numbers of closures, perhaps in scenarios with large numbers of concurrent active observables, an object will use less mem. I'm still concerned about allowing observables to deliver events before |
@briancavalier Regarding the return type, feel free to join in the discussion at tc39/proposal-observable#48 As far as zalgo goes, let me explain how I came to my current position. First, I think zalgo avoidance is important, and that's why I have I've always been against the idea of having two subscription methods which differ only in sync-vs-async subscription behavior, since subtle differences like that will most likely only result in confusion. I briefly toyed with the idea of "next", etc, throwing an error if invoked before So my current position is basically that creators of Observable should, as a best practice, follow the lead of Thoughts? |
Hey everyone, what does Zalgo mean...? |
@jasonkuhrt In this context, it means situations where sometimes a callback will execute synchronously (before the function call returns) and sometimes asynchronously. This can lead to difficult-to-reproduce errors. Promises avoid zalgo by always invoking their success and error handlers in a future turn of the event loop. |
Thanks @zenparsing. Sorry I haven't had time to respond yet :/ I'll try to soon. @jasonkuhrt what @zenparsing said :) |
This will enable Most to interop with Kefir, RxJS and libraries like Redux Related cujojs#160
ES7 Observable interop is nearly done in #254. |
Hey @briancavalier! I know you and @jhusain and I talked a few months ago about interop between reactive streaming libraries like this and I'm here to offer a little help bridging that gap.
we've been working hard on the next version of RxJS, and we're getting closer. Part of that work was to try to adhere to the current ES7 Observable spec by @zenparsing. The part of particular interest there for this library is the
[Symbol.observable]()
method.Implementing [Symbol.observable]
Really all that is involved with that is to add a
[Symbol.observable]()
method to your streaming type, and have it return any object with asubscribe(observer)
method, and a[Symbol.observable]()
method.The benefits here are:
I think a basic implementation might look like:
Consuming "lowercase-o" observables...
On your end, you could implement something inside of your
from
method to handle any type with a[Symbol.observable]
method on it. As a guineapig you can use@reactivex/rxjs
over npm, if you choose. Again it's pretty basic. You'd just call[Symbol.observable]()
then callsubscribe(observer)
on the returned object, where observer hasnext
,error
andcomplete
methods.Other things...
I've actively tried to make any monadic-bind-esque operator in RxJS Next support objects that implement
Symbol.observable
. This means, effectively that if you were to implement this, people could jump between Most.js and RxJS using flatMaps and switches, etc. I'll be reaching out to the Bacon.js community with the same information.The text was updated successfully, but these errors were encountered: