-
-
Notifications
You must be signed in to change notification settings - Fork 927
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
Add stream.observe() #2713
Comments
This could easily live in userland. I tend to close this 🤔 |
I feel this should be split into two separate proposals, one for async
@StephanHoyer Ordinarily I'd say yes, but this one could be reasonably defended:
|
I vote userland for numerous reasons. I think @nordfjord said it best:
paldepind/flyd#194 (comment) and discussion in paldepind/flyd#167 But a short list why I think this shouldn't be added:
|
Ok, then we close this. Hope it's ok for you @soulofmischief |
@StephanHoyer Sounds good to me. So one example of where I'm using this is to asynchronously fetch the total number of results from a query, after updating another stream containing the query string.
It seemed like a straightforward extension as my query was already a stream (following the bidirectional input binding pattern in the docs). Would you recommend not (ab)using streams in this way? I can see how it would be an anti-pattern but I liked the terseness and clarity. |
@soulofmischief it is not abusing it, it just pulls mithril in a direction that would be out of scope. If you are using a library like Rx/most.js/xstream etc it is pretty normal and encouraged to model everything as observables, and avoid subjects (in Rx parlance). But that necessitates having a lot of operators to model all the common/general ways to interact with n streams. Flyd and mithril treat their streams as more of a channel, it is fine to write to a stream in mithril or flyd, and because it is encouraged, it means you don't need as many operators, as you can just implement them in situ by writing to the stream yourself. E.g. Rx might have let click$ = stream();
window.addEventListener('click', click$)
click$.end.map( () => window.removeEventLIstener('click', click$) ) Rx is handling error, clean up, replays, parameterized schedulers, etc. And they have operators for everything imaginable to ensure you almost never need to write to a stream. In that world, it makes sense to flatten promises into streams and have operators that flatten in different ways. It also helps Rx observables have an error channel. To start to go down this path would lead to complexity and would tacitly endorse that complexity, which isn't in the spirit of mithril (I think). And that isn't to say complexity is bad, it just often isn't needed, or can be avoided. But it is not an anti-pattern, or abuse in anyway. I recommend if you want to explore those patterns, try out xstream, callbags, Rx, most etc. All great libraries. That approach to reactivity will lead you toward needing more operators, but all those operators are covered by those libraries. Arguably those libraries are all more "pure", but there is a complexity cost. Alternatively check out flyd and their promise conversion utils which is probably an ideal middle ground. Mithril works great with all these options, but mithril's stream offering is deliberately lightweight. Hope that helps :) |
@JAForbes thanks for reaching out, I appreciate the recommendations, I will check out the other libraries you mentioned. I already use Rx a good bit which is another reason I embrace mithril streams. Observables definitely keep things organized. What I did a couple months ago was just make a personal library for these stream extensions. I think I'll add a fromEvent inspired by the snippet you provided. If it ever gets large enough one day I'll pop into gitter and see if I can get some optimization advice / official endorsement. By the way, a little off-topic but I checked out your website; love the music, good blog content as well. I think we have much in common and would like to chat a bit, what is the best way to reach you that isn't Twitter? |
Description
Add
stream.observe
to allow an idiomatic way to observe potentially async parent streams.Implementation
Usage
Why
The standard approach of
stream.map(() => m.redraw())
doesn't account for async streams.Is this something you're interested in implementing yourself?
Yes.
Open Questions
Should this behavior be split (e.g.
stream.observe
/stream.observeSync
or inversed) in order to provider an idiomatic wrapper around thestream.map(() => m.redraw())
pattern without the async overhead?Should the redraw callback be exposed or is it better to assume it will always be
m.redraw
?Is there a performant Promise.all polyfill for IE? Otherwise if IE support for this particular method is dropped then this code can also be rewritten to use async/await instead of a callback.
The text was updated successfully, but these errors were encountered: