1. 程式人生 > 實用技巧 >[Javascript] Broadcaster + Operator + Listener pattern -- 9. Create modify, filter, map operators

[Javascript] Broadcaster + Operator + Listener pattern -- 9. Create modify, filter, map operators

import { curry } from 'ramda';

// #region listeners
const _log = (value) => console.log(value);
// #endregion

// #region broadcasters
const done = Symbol('done');
const addListener = curry((element, eventType, listener) => {
  return element.addEventListener(evenType, listener);
});
const createInterval 
= curry((time, listener) => { let i = 0; const id = setInterval(() => { listener(i++); }, time); return () => { clearInterval(id); }; }); const createForOf = curry((iterator, listener) => { const id = setTimeout(() => { for (let item of iterator) { listener(item); } listener(done); },
0); return () => { clearTimeout(id); }; }); const createZipOf = curry((broadcaster1, broadcaster2, listener) => { let cancelBoth; let buffer1 = []; const cancel1 = broadcaster1((value) => { buffer1.push(value); if (buffer2.length) { listener([buffer1.shift(), buffer2.shift()]);
if (buffer1[0] === done || buffer2[0] === done) { listener(done); cancelBoth() } } }); let buffer2 = []; const cancel2 = broadcaster2((value) => { buffer2.push(value); if (buffer1.length) { listener([buffer1.shift(), buffer2.shift()]); if (buffer1[0] === done || buffer2[0] === done) { listener(done); cancelBoth() } } }); cancelBoth = () => { cancel1(); cancel2(); } return cancelBoth; }); // #endregion // #region operators const modify = curry((broadcaster, listener) => { let string = ''; return broadcaster((value) => { if (value === done) { listener(done); return; } listener((string += value)); }); }); const map = curry((transform, broadcaster, listener) => { return broadcaster((value) => { if (value === done) { listener(done); return; } listener(transform(value)); }); }); const filter = curry((predicator, briadcaster, listener) => { return broadcaster((value) => { if (value === done) { listener(done); return; } listener(predicator(value)); }); }); // #endregion