cou*_*udy 4 javascript frp bacon.js
我一直在关注这个蛇的例子,并决定修改它以仅在空(即非蛇)单元格中生成新苹果。然而,这在 Observables 之间引入了循环依赖,因为现在生成新苹果不仅取决于最后一个位置,还取决于整条蛇:
// stream of last `length` positions -- snake cells
var currentSnake = currentPosition.slidingWindowBy(length);
// stream of apple positions
var apples = appleStream(currentSnake);
// length of snake
var length = apples.scan(1, function(l) { return l + 1; });
Run Code Online (Sandbox Code Playgroud)
有没有解决循环的好方法?
我可以想象这在凌乱的状态机中如何工作,但在干净的 FRP 中则不然。
我能想到的最接近的是合并apples并length成为一个流,并使该流"currentSnake"从currentPosition.
applesAndLength --> currentPosition
^ ^
| /
currentSnake
Run Code Online (Sandbox Code Playgroud)
不过,我还没有考虑太多实现。
一旦构建完成,Bacon 通常可以处理Observables之间的循环依赖。构建它们有点棘手。
在像 Javascript 这样的语言中,要创建一个包含循环的结构(即双向链表),您需要一个可变变量。对于常规对象,您使用常规变量或字段来执行此操作,例如
var tail = { prev: null, next: null };
var head = { prev: null, next: tail };
tail.prev = head; // mutating 'tail' here!
Run Code Online (Sandbox Code Playgroud)
在 Bacon 中,我们操作的是 Observables 而不是变量和对象,所以我们需要某种可变的 observable 来达到相同的目的。值得庆幸的是,Bacon.Bus这正是我们需要的那种 observable:
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!
Run Code Online (Sandbox Code Playgroud)
根据我的经验,最好在EventStreams 而不是处切断循环Properties,因为否则初始值往往会丢失;因此重新排序apples和length。
| 归档时间: |
|
| 查看次数: |
288 次 |
| 最近记录: |