[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, broadcaster, listener) => {
  return broadcaster((value) => {
    if (value === done) {
      listener(done);
      return;
    }
    if(predicator(value)) {
listener(value)
} }); });
// #endregion

 

posted @ 2020-10-25 17:45  Zhentiw  阅读(112)  评论(0编辑  收藏  举报