Last active
November 11, 2015 13:43
-
-
Save nikcorg/ac0388d594400e6a8e99 to your computer and use it in GitHub Desktop.
Flat Map Latest (through events)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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