Skip to content

Instantly share code, notes, and snippets.

@mendaomn
Created March 29, 2020 17:13
Show Gist options
  • Save mendaomn/588d970d5fe13219ebe99d84070d2300 to your computer and use it in GitHub Desktop.
Save mendaomn/588d970d5fe13219ebe99d84070d2300 to your computer and use it in GitHub Desktop.
Naive implementation of an Observable. This is just an exercise to help me learning this pattern
class Observable {
static fromPublisher(publisher) {
return new Observable({
publisher
})
}
static fromObservable(observable, extentions) {
return new Observable({
...observable,
...extentions
})
}
constructor ({publisher, transformations = []}) {
this.publisher = publisher
this.transformations = transformations
}
map (mapper) {
const transformation = {
type: 'mapper',
fn: mapper
}
return Observable.fromObservable(this, {
transformations: this.transformations.concat(transformation)
})
}
filter (filterFn){
const transformation = {
type: 'filter',
fn: filterFn
}
return Observable.fromObservable(this, {
transformations: this.transformations.concat(transformation)
})
}
forEach (callback) {
this.publisher.subscribe(value => {
const transformedValue =
this.transformations.reduce((partial, transformation) => {
if (typeof partial === 'undefined') return undefined
const { type, fn } = transformation
if (type === 'mapper') return fn(partial)
if (type === 'filter') return fn(partial) ? partial : undefined
}, value)
if (typeof transformedValue === 'undefined') return
return callback(transformedValue)
})
}
}
function tests() {
const publisher = {
subscribe: cb => this.sub = cb,
emit: (value) => this.sub(value)
}
const observable = Observable.fromPublisher(publisher)
observable
.filter(value => value % 2 !== 0)
.map(value => value + 1)
.map(value => value * 2)
.forEach(value => console.log(value))
let counter = 0
const interval = setInterval(() => {
if (counter >= 20) {
clearInterval(interval)
}
publisher.emit(counter)
counter++
}, 50)
}
tests()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment