After a broadcaster is "done", starting it up again requires calling the broadcaster with the same listener. This creates a kind of "async recursion" where you pass the listener back into the broadcaster each time you set it up. This lesson walks through creating a repeat operator that can start a broadcaster over.
Idea for Repeat operator, is that when source broadcaster emit done, then in repeat operator call the broadcaster(repeatListener) again.
let repeat = (broadcaster) => (listener) => { let cancel; let repeatListener = (value) => { if (value === done) { if (cancel) { cancel(); } cancel = broadcaster(repeatListener); return; } listener(value); }; cancel = broadcaster(repeatListener); return () => { cancel(); }; };
import { createTimeout, done } from "./broadcasters"; import { hardCode } from "./operators"; let repeat = (broadcaster) => (listener) => { let cancel; let repeatListener = (value) => { if (value === done) { if (cancel) { cancel(); } cancel = broadcaster(repeatListener); return; } listener(value); }; cancel = broadcaster(repeatListener); return () => { cancel(); }; }; let one = repeat(hardCode("hi")(createTimeout(1000))); let cancel = one(console.log); setTimeout(() => { cancel(); }, 5000); // broadcasters.js import { curry } from "lodash" export let done = Symbol("done") export let createTimeout = curry((time, listener) => { let id = setTimeout(() => { listener(null) listener(done) }, time) return () => { clearTimeout(id) } }) // operators.js import { curry } from "lodash"; import { done } from "./broadcasters"; let createOperator = curry((operator, broadcaster, listener) => { return operator((behaviorListener) => { return broadcaster((value) => { if (value === done) { listener(done); return; } behaviorListener(value); }); }, listener); }); export let hardCode = (newValue) => createOperator((broadcaster, listener) => { let cancel = broadcaster((value) => { listener(newValue); }); return () => cancel(); });