Apps often have scenarios where one event controls another. In operators, this requires passing one broadcaster in and using it to control another broadcaster. You can think, "when this broadcaster fires, do that with the other broadcaster". This lesson covers using one broadcaster to control when another broadcaster repeats.
import { addListener, done, forOf } from "./broadcasters"; const log = console.log; // only when listener receive DONE event // then broadcaster should trigger the listener again // otherwise, keep emit value let repeat = (broadcaster) => (listener) => { let cancel; let repeatListener = (value) => { // when it is doen event if (value === done) { // because it is repeated event // need to cancel previous one if (cancel) { cancel(); } // broadcaster should trigger the listener again cancel = broadcaster(repeatListener); return; } // otherwise, keep emitting value listener(value); }; cancel = broadcaster(repeatListener); return () => cancel(); }; // Only when 'whenBroadcater' happen then do the repeat logic let repeatWhen = (whenBroadcaster) => (mainBroadcaster) => (listener) => { let mainCancel; let whenCancel; let repeatListener = (value) => { if (value === done) { if (mainCancel) { mainCancel(); } whenCancel = whenBroadcaster(() => { // cancel previous when broadcaster whenCancel(); mainCancel = mainBroadcaster(repeatListener); }); } listener(value); }; mainCancel = mainBroadcaster(repeatListener); return () => { mainCancel(); whenCancel(); }; }; const inputClick = addListener("#input", "click"); const printCat = forOf("cat"); const repeatCatOnClick = repeatWhen(inputClick)(printCat); const cancel = repeatCatOnClick(log); setTimeout(() => { cancel(); }, 3000);