Skip to content

Instantly share code, notes, and snippets.

@nikcorg
Last active November 11, 2015 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikcorg/ac0388d594400e6a8e99 to your computer and use it in GitHub Desktop.
Save nikcorg/ac0388d594400e6a8e99 to your computer and use it in GitHub Desktop.
Flat Map Latest (through events)
export const VALUE = Symbol("VALUE");
const attempt = (fn, ...args) => {
try {
return fn(...args)
} catch (e) {}
}
const listen = function (event, cb) {
const eProp = Symbol.for(event);
if (!this.hasOwnProperty(eProp)) {
this[eProp] = [];
}
const listeners = this[eProp];
if (-1 === listeners.indexOf(cb)) {
listeners.push(cb);
}
return unlisten.bind(this, event, cb);
};
const unlisten = function (event, cb) {
const eProp = Symbol.for(event);
if (!this.hasOwnProperty(eProp)) {
return;
}
const listeners = this[eProp].filter(listener => cb !== listener);
this[eProp] = listeners;
}
const emit = function (event, payload) {
const eProp = Symbol.for(event);
if (!this.hasOwnProperty(eProp)) {
return;
}
const listeners = this[eProp];
listeners.forEach(cb => attempt(() => cb(payload)));
};
const makeEmitter = fn => {
fn.on = listen.bind(fn);
fn.off = unlisten.bind(fn);
fn.emit = emit.bind(fn);
return fn;
};
const makeRunner = fn => (jobId, args) => {
return fn(...args).then(ret => ({ jobId, ret }));
};
export const flatMapLatest = fn => {
let latestJobId = 0;
const runner = makeRunner(fn);
const flatMapper = makeEmitter((...args) => runner(++latestJobId, args).then(job => {
if (job.jobId < latestJobId) {
return;
}
flatMapper.emit(VALUE, job.ret);
}, err => console.error(err)));
return flatMapper;
}
export { fml as default };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment