Frage

In my application I have a state object state, which is mutated by GUI elements. Each time this state is mutated, an XHR is executed to update the state server-side and current state is returned. This maps nicely to Bacon.js' streams.

Now, assuming a mutation stream mutationEventStream, I'm trying to update my state by combining previous state value with the event trigger:

Bacon.onValues(state, mutationEventStream, function(data, event) {
    dataUpdateBus.push(/* extract data from event */)
})

(dataUpdateBus contains all data updates which need to go the server. state is what is returned by the XHR initiated with data on the dataUpdateBus)

My problem is now that I need a current state value to properly update it. If I had a global variable, I'd only need new events on the mutationEventStream, but with streams I need to mix-in my state stream. With the code above I'm getting every update of state, i.e. with data updates it's effectively an endless loop (dataUpdateBus.push -> XHR -> state -> dataUpdateBus.push, etc.). And since state is updated more frequently than mutationEventStream I can't use Bacon.zip().

What am I doing wrong and what can I do better?

War es hilfreich?

Lösung

If I understood correctly, you want to combine each new value in mutationStream with the current value of state, but you don't want to trigger updates when state changes (that causes a "feedback" effect). The sampledBy combinator allows use to do just this:

var stateUpdates = state.sampledBy(mutationStream, function(currentState, newEvent) {
  return currentState.updatedWith(newEvent)
}).onValue(dataUpdateBus.push)

The key difference to your code is that updates are only generated on new events in the mutationStream.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top