Making Observable better

This commit is contained in:
Stamm 2019-03-21 11:29:07 -04:00
parent e340d9f0f0
commit 3e25b10266
4 changed files with 59 additions and 41 deletions

View File

@ -1,2 +0,0 @@
src/
node_modules/

View File

@ -1,6 +1,6 @@
{ {
"name": "@hibas123/utils", "name": "@hibas123/utils",
"version": "1.0.2", "version": "2.0.0",
"description": "Different Utilities, that are not worth own packages", "description": "Different Utilities, that are not worth own packages",
"main": "lib/index.js", "main": "lib/index.js",
"types": "lib/index.d.ts", "types": "lib/index.d.ts",
@ -18,5 +18,10 @@
"devDependencies": { "devDependencies": {
"typescript": "^3.3.3333" "typescript": "^3.3.3333"
}, },
"files": [
"lib/",
"tsconfig.json",
"readme.md"
],
"private": false "private": false
} }

View File

@ -1,9 +1,11 @@
import Lock, { Release } from "./lock"; import Lock, { Release } from "./lock";
import Observable, { ObserverCallback } from "./observable"; import Observable, { ObserverCallback, ObserverCallbackCollect, ObservableInterface } from "./observable";
export { export {
Lock, Lock,
Release, Release,
Observable, Observable,
ObserverCallback ObserverCallback,
ObserverCallbackCollect,
ObservableInterface
} }

View File

@ -1,39 +1,58 @@
export type ObserverCallback<T> = (data: T[]) => void; export type ObserverCallbackCollect<T> = (data: T[]) => void;
export type ObserverCallback<T> = (ata: T) => void;
export type ObservableInterface<T> = {
/**
* Subscribe to Observable
* @param {function} callback
*/
subscribe: (callback: ObserverCallback<T>) => void;
/**
* Unsubscribe fron Observable
* @param {function} callback
*/
unsubscribe: (callback: ObserverCallback<T>) => void;
/**
* Subscribe to Observable in collect mode
* @param {function} callback
*/
subscribeCollect: (callback: ObserverCallbackCollect<T>) => void;
};
export default class Observable<T = any> { export default class Observable<T = any> {
private subscriber: { callback: ObserverCallback<T>, one: boolean }[] = []; private subscriber: ObserverCallback<T>[] = [];
private subscriberCollect: ObserverCallbackCollect<T>[] = [];
private events: T[] = []; private events: T[] = [];
private timeout: number | undefined = undefined; private timeout: NodeJS.Timeout | number | undefined = undefined;
constructor(private collect: boolean = true, private collect_intervall: number = 100) { } constructor(private collect_intervall: number = 100) { }
/** /**
* Creates Public API with subscribe and unsubscribe * Creates Public API with subscribe and unsubscribe
* *
* @returns {object} * @returns {object}
*/ */
getPublicApi() { getPublicApi(): ObservableInterface<T> {
return { return {
/** subscribe: (callback: ObserverCallback<T>) => {
* Subscribe to Observable let oldcb = this.subscriber.find(e => e === callback);
* @param {function} callback if (!oldcb)
*/ this.subscriber.push(callback)
subscribe: (callback: ObserverCallback<T>, one: boolean = false) => {
let oldcb = this.subscriber.find(e => e.callback === callback);
if (oldcb)
oldcb.one = one
else
this.subscriber.push({ callback, one })
}, },
/** unsubscribe: (callback: ObserverCallback<T> | ObserverCallbackCollect<T>) => {
* Subscribe fron Observable let idx = this.subscriber.findIndex(e => e === callback);
* @param {function} callback
*/
unsubscribe: (callback: ObserverCallback<T>) => {
let idx = this.subscriber.findIndex(e => e.callback === callback);
if (idx >= 0) { if (idx >= 0) {
this.subscriber.splice(idx, 1); this.subscriber.splice(idx, 1);
} else {
idx = this.subscriberCollect.findIndex(e => e === callback);
if (idx >= 0)
this.subscriberCollect.splice(idx, 1);
} }
},
subscribeCollect: (callback: ObserverCallbackCollect<T>) => {
let oldcb = this.subscriberCollect.find(e => e === callback);
if (!oldcb)
this.subscriberCollect.push(callback)
} }
} }
} }
@ -43,21 +62,15 @@ export default class Observable<T = any> {
* @param data data to be sent * @param data data to be sent
*/ */
send(data: T) { send(data: T) {
if (!this.collect) this.subscriber.forEach(e => e(data));
this.subscriber.forEach(e => e.callback([data])); this.events.push(data);
else { if (!this.timeout) {
this.events.push(data); this.timeout = setTimeout(() => {
if (!this.timeout) { this.subscriberCollect.forEach(cb => {
this.timeout = setTimeout(() => { cb(this.events)
this.subscriber.forEach(cb => { });
if (cb.one) this.timeout = undefined;
this.events.forEach(e => cb.callback([e])); }, this.collect_intervall);
else
cb.callback(this.events)
});
this.timeout = undefined;
}, this.collect_intervall);
}
} }
} }
} }