Once it has been constructed, Bacon can usually handle a cyclic dependency between Observable
s. It is constructing them that's a bit tricky.
In a language like Javascript, to create a structure with a cycle in it (i.e. a doubly-linked list), you need a mutable variable. For regular objects you use a regular variable or field to do that, e.g.
var tail = { prev: null, next: null };
var head = { prev: null, next: tail };
tail.prev = head; // mutating 'tail' here!
In Bacon, we operate on Observables instead of variables and objects, so we need some kind of a mutable observable to reach the same ends. Thankfully, Bacon.Bus
is just the kind of observable we need:
var apples = new Bacon.Bus(); // plugged in later
var length = apples.scan(1, function(l) { return l + 1; });
var currentSnake = currentPosition.slidingWindowBy(length);
apples.plug(appleStream(currentSnake)); // mutating 'apples' here!
In my experience, it is preferrable to cut the cycles at EventStream
s instead of Properties
, because initial values tend to get lost otherwise; thus the reordering of apples
and length
.