2014-04-17 2 views
3

나는 this snake example을 따라 왔으며 비어있는 (즉, 뱀이 아닌) 셀에만 새 사과를 생성하도록 수정했습니다.Bacon.js의 FRP 뱀주기를 깨기

// 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; }); 

주기를 해결할 수있는 좋은 방법이 있나요 : 새로운 사과를 생성하는 이제 마지막 위치에 있지만 전체 뱀에뿐만 아니라 의존하기 때문에, 즉, Observable 인 사이의 순환 종속성을 도입거야?

이것은 지저분한 상태 기계에서는 작동하지만 클린 FRP에서는 작동하지 않을 것이라고 생각합니다.

내가 하나 개의 스트림으로 appleslength을 병합하고 스트림을하고있다 생각할 수있는 가장 가까운 currentPosition에서 "currentSnake" 자체를 생성합니다.

applesAndLength --> currentPosition 
     ^  ^
     |  /
     currentSnake 

구현에 대해서는별로 생각하지 않았습니다.

답변

4

일단 구성되면 Bacon은 보통 Observable 사이의 주기적 종속성을 처리 할 수 ​​있습니다. 조금 까다 롭습니다.

자바 스크립트와 같은 언어에서주기가 포함 된 구조 (즉, 이중 연결 목록)를 만들려면 가변 변수가 필요합니다. 일반 객체의 경우 일반 변수 또는 필드를 사용합니다. 베이컨에서

var tail = { prev: null, next: null }; 
var head = { prev: null, next: tail }; 
tail.prev = head; // mutating 'tail' here! 

, 우리는 Observables은 대신 변수와 객체에서 작동, 그래서 우리는 같은 목적을 달성하기 위해 가변 관찰의 일종이 필요합니다. 다행히, Bacon.Bus는 우리가 필요로하는 관찰의 단지 종류 : 내 경험에

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! 

초기 값이 다른 길을 잃을 경향이 있기 때문에, EventStream의 대신 Properties에서 사이클을 잘라보다 더 낫다이다; 따라서 appleslength의 순서가 변경되었습니다.