Comments (7)
How did you notice the odd state$
emissions? I'm asking because I would expect the state$
to catch up before the screen is even drawn the first time, so that no flash can be seen.
There are many cases in which a complex network of streams can emit superfluous events, but that's fine as long as the right events are emitted at the right times, and the state of the app is always consistent, if odd at moments. Javascript is synchronous, it has no such thing as simultaneous events. We can't overcome Javascript's limitations, but by using streams, which operate at a higher level of abstraction, we should be able to ignore those limitations. The order in which streams are merged shouldn't change the overall behavior of the app. The question is then: why can't you ignore the superfluous emissions of state$
?
Personally I'd like to keep the possibility to omit the default reducer in a component.
from cycle-onionify.
The question is then: why can't you ignore the superfluous emissions of state$?
You can't literally ignore superfluous emissions of state. You can't pretend they don't exist. My view functions assume the truthiness of certain pieces of state. When those pieces of state are invalid/not-truthy, the view crashes. This is not about avoiding a flash. It's about a crash.
To "ignore" in this context means...
- Knowing they happen (which, in a sense means you're not ignorant)
- Using a technique to filter on them
The technique I tend to use is proper merge stream ordering and when that fails, adding truthiness guards in my view functions (and sometimes adding a state-validity flag). These are things I didn't have to do when I maintained my state local to my components.
Am I missing something? Is there a way to actually pretend invalid states don't exist without causing crashes? Maybe using requestAnimationFrame
in a clever way offers an approach?
I can see how omitting a default reducer can be useful. I'm just trying to think of ways to avoid invalid states. At the very least, this issue should be documented.
from cycle-onionify.
By "ignore emissions" I mean "be indifferent to emissions", i.e. robust. I think it's a common situation, I run into something similar every now and then. Anyway I think your problem should be solved differently.
Your parent component assumes the state to satisfy certain requirements, which are enforced by its own default reducer, but at the same time it merges its reducers with the two children reducers in a way that doesn't determine their relative order. By using merge
you can't know (in theory) in which order the reducers will emit. That's the problem. Your component needs its default reducer to emit first, but does nothing explicit for that to happen.
This should explicitly enforce that the default reducer emits first:
const defaultReducer$ = ... // the local default reducer
const otherReducer$ = ... // other local reducers
const subsequentReducer$ = O.merge(A.onion, B.onion, otherReducer$)
return {
...
onion: O.concat(defaultReducer$, subsequentReducer$)
}
from cycle-onionify.
Perfect. That solves the issue elegantly. concat
has not been a goto operator for me, but it will be now! 👍
from cycle-onionify.
Cool that abaco already answered it. I would also add a .take(N)
to each participating stream in the concat
, just to make sure that concatenation actually happens instead of hanging forever if one of the participating streams doesn't complete.
Even though this is closed/answered, I'm still curious about the "can't ignore state emissions" part. I would also say like abaco, that state emissions can be ignored, they should be skippable. If you have some boolean flag and you are creating an event (e.g. component instantiation is an event) whenever the boolean flips, that seems to me like converting from state to event, while in the first place some event caused the boolean flip. So you could theoretically shortcut, avoid the state as an intermediate, and just have a direct dependency between first event and second event.
For example:
const click$; // event
const toggle$ = click$.startWith(false).scan(prev => !prev, false); // state
const alert$ = toggle$.filter(Boolean).map(() => 'alert!'); // event
alert$.subscribe(x => window.alert(x));
simplified to
const click$; // event
const alert$ = click$.map(() => 'alert!'); // event
alert$.subscribe(x => window.alert(x));
from cycle-onionify.
@staltz What does it mean for a state emission to be skippable
? Do you mean, it's okay to filter state emissions?
from cycle-onionify.
I'd answer a soft yes, not a hard yes.
from cycle-onionify.
Related Issues (20)
- pickCombine fails when re-adding item with same key HOT 1
- Rename lens getter/setter HOT 8
- Help needed - MemoryStream.map not producing output HOT 1
- Add mock-onionify HOT 4
- Remove the .vscode folder
- Why don't provide 'pick' and 'mix' functions in xstream? HOT 4
- Shouldn't collections docs be in readme as well as release notes? HOT 2
- Add ES6 module build
- "Reducer" term is not correct HOT 1
- pickMerge throws error if child is not using sink HOT 1
- pickMerge seems to swallow events HOT 6
- type MakeScopesFn does not exist but imported HOT 1
- Shouldn't state emissions be microtask queued? HOT 6
- emitting `xs.never` with pickCombine might be wrong HOT 13
- Action stream is probably a better definition than `reducer` stream. HOT 4
- onionify typings assume "onion" as key HOT 1
- cycle-onionify when can update for rxjs@6
- cannot compile typescript examples HOT 1
- Define Omit<T, K> properly? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cycle-onionify.