Skip to content

Instantly share code, notes, and snippets.

@arielshaqed
Last active July 16, 2018 10:41
Show Gist options
  • Save arielshaqed/14369a7b3d6383ef5e0d8b5075804954 to your computer and use it in GitHub Desktop.
Save arielshaqed/14369a7b3d6383ef5e0d8b5075804954 to your computer and use it in GitHub Desktop.
RxJS feedback loop using Rx.Subject
// DO NOT SUBMIT: Code for teaching ariels to feed state back through
// RxJS.
import { test } from 'ava';
import * as Rx from 'rxjs';
import { List } from 'immutable-sorted';
class State {
private constructor(private lastN: List<number>, private num: number) {}
public static make(num: number): State { return new State(List(), num); }
public push(a: number): State {
const newLast = List(this.lastN.push(a).slice(-this.num));
return new State(newLast, this.num);
}
public avg(): number {
const sum = this.lastN.reduce((a, b) => a! + b!, 0);
return sum / this.num;
}
}
test('feedback', async (t) => {
const state = new Rx.Subject<State>();
const avgs = [] as number[];
const c = Rx.Observable.interval(100)
.withLatestFrom(state)
.map(([n, s]) => [n, s.push(n)] as [number, State])
.do(([_, s]) => state.next(s))
.take(8)
.forEach(([_, s]) => avgs.push(s.avg()));
state.next(State.make(4));
await c;
t.deepEqual([0, 0.25, 0.75, 1.5, 2.5, 3.5, 4.5, 5.5], avgs);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment