Skip to content

Instantly share code, notes, and snippets.

@vilindberg
Last active December 12, 2018 22:18
Show Gist options
  • Save vilindberg/39745088aabca377309e53b2d9015a29 to your computer and use it in GitHub Desktop.
Save vilindberg/39745088aabca377309e53b2d9015a29 to your computer and use it in GitHub Desktop.
playing with my own observable
class Observable {
constructor({ initFn, element, eventName }) {
if (initFn) {
this._initFn = initFn
}
else if (element && eventName) {
this._event = {
listener: event => {
this.next(event)
},
element,
eventName
}
this._event.element.addEventListener(eventName, this._event.listener)
}
this.listeners = []
}
static create(initFn) {
return new Observable({initFn})
}
static from(input) {
let initFn
if (input.constructor === Array) {
initFn = observer => {
input.forEach(i => observer.next(i))
}
}
else if (typeof input.then === 'function') {
initFn = observer => {
input.then(res => {
observer.next(res)
})
}
}
else if (typeof input === 'string' || typeof input[Symbol.iterator] === 'function') {
initFn = observer => {
for (let char of input) {
observer.next(char)
}
}
}
return new Observable({initFn})
}
static fromEvent(element, eventName) {
return new Observable({element, eventName})
}
subscribe(cb) {
this.listeners.push(cb)
if (this._initFn)
this._initFn(this)
return {
unsubscribe: () => {
this.listeners = this.listeners.filter(l => l !== cb)
if (this.listeners.length === 0 && this._event) {
this._event.element.removeEventListener(this._event.eventName, this._event.listener)
}
}
}
}
next(value) {
this.listeners.forEach(cb => cb(value))
}
}
const hello = Observable.create(function(observer) {
observer.next('Janne');
});
const helloSubscribe = hello.subscribe(val => console.log(val));
hello.next('JANNE')
helloSubscribe.unsubscribe()
hello.next('JANNE')
const array = Observable.from([1,2,3])
array.subscribe(val => console.log(val))
const string = Observable.from('string')
string.subscribe(val => console.log(val))
const promise = Observable.from(new Promise(resolve => resolve('PROMISE')))
promise.subscribe(val => console.log(val))
const map = new Map();
map.set(1, 'Jan');
map.set(2, 'Josef');
const fromMap = Observable.from(map)
fromMap.subscribe(val => console.log(val))
const div = document.createElement('div')
const fromEvent = Observable.fromEvent(div, 'click')
const subscription = fromEvent.subscribe(event => console.log(event))
div.click()
subscription.unsubscribe()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment