Giter VIP home page Giter VIP logo

Comments (7)

abaco avatar abaco commented on June 16, 2024

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.

ntilwalli avatar ntilwalli commented on June 16, 2024

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...

  1. Knowing they happen (which, in a sense means you're not ignorant)
  2. 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.

abaco avatar abaco commented on June 16, 2024

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.

ntilwalli avatar ntilwalli commented on June 16, 2024

Perfect. That solves the issue elegantly. concat has not been a goto operator for me, but it will be now! 👍

from cycle-onionify.

staltz avatar staltz commented on June 16, 2024

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.

ntilwalli avatar ntilwalli commented on June 16, 2024

@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.

staltz avatar staltz commented on June 16, 2024

I'd answer a soft yes, not a hard yes.

from cycle-onionify.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.