kefirjs / kefir

A Reactive Programming library for JavaScript
https://kefirjs.github.io/kefir/
MIT License
1.87k stars 97 forks source link

When property deactivates the current value of it should be removed #59

Open rpominov opened 9 years ago

rpominov commented 9 years ago

... so properties will not store potentially outdated current value. This was originally suggested by @raimohanska here https://github.com/baconjs/bacon.js/issues/536#issuecomment-72805294

markmarijnissen commented 9 years ago

What if:

Is the combined stream a property?

rpominov commented 9 years ago

Yeah, might be a problem here.

The result of .combine is a stream, not a property. One can easily convert it to a property by doing .combine(...).toProperty(). But here is a problem that intermediate stream will prevent result property to get fresh current value on reactivation from original properties.

This issue also presented now, without change of properties behavior. It's actually a separate issue (created one: #68).

To be honest I'm not sure I answered your question :) It just made me think about .combine and current values handling.

rpominov commented 9 years ago

Not a big issue after some thoughts https://github.com/rpominov/kefir/issues/68#issuecomment-77561863

rpominov commented 9 years ago

This one harder than I thought. For example, with this new semantics Kefir.constant() simply can't be implemented. Because a property can't have current value while not active, .constant is an ended property, and an ended observable never becomes active. Perhaps we should fix the last bit of it ("an ended observable never becomes active").

Also a lot of tests are failing, which is totally fixable of course, but will require more time.

raimohanska commented 9 years ago

An ended Property will always retain its final value, so there's no need to remove it. So removing would only be necessary for non-ended Properties on deactivation. Yes?

raimohanska commented 9 years ago

Your hard work makes me feel a bit quilty for being so inactive lately. I have very good excuses of course ;)

rpominov commented 9 years ago

Yeah, I also thought of introducing something like final value which remains after the end, but it looked as a semantically incorrect hack to me. But perhaps we should make it part of the semantics. I'll experiment in this direction.

To be honest I also didn't work too hard lately, although had enough chances. But you shouldn't feel guilty in any case, it's open source after all :)

rpominov commented 9 years ago

I think we'll do it in v3.0.0. The issue is not critical but requires too much code to be changed, and too many small yet important decisions to be made. May happen we will do a complete rewrite for v3.0.0, so it will be easier then.

Macil commented 9 years ago

Retaining the end value would match up nicely with one pattern I've used a few times.

const buttonStream = Kefir.fromPoll(
  100, () => document.querySelector("#foo")
).filter(Boolean).take(1).toProperty();

export function clickButtonWhenAvailable() {
  buttonStream.onValue(button => button.click());
}

(This is in a browser extension where the foo element is made by the page itself; this would be a little silly to track an element we were responsible for ourselves. I also have similar functions that make streams out of mutation observers in order to get elements as soon as they show up and without polling, but it's not the focus of this example.)

rpominov commented 9 years ago

Yeah, we will certainly retain that behavior.