Add AwaitStore

This commit is contained in:
Fabian Stamm 2019-11-25 21:31:22 +01:00
parent edd37246fb
commit 0781323acb
5 changed files with 130 additions and 5 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@hibas123/utils",
"version": "2.1.1",
"version": "2.2.0",
"description": "Different Utilities, that are not worth own packages",
"main": "lib/index.js",
"types": "lib/index.d.ts",

View File

@ -35,8 +35,8 @@ Usage:
const server = new Observable(); // Get new Observable Server
// Server can only send, not subscribe to messages
// Receiving is only possible via the public API
// Server can send and subscribe to messages
// The publicAPI will only make the receiving parts available
const public = server.getPublicApi();
const func = (data)=>{
@ -44,10 +44,15 @@ Usage:
}
// func will be callen when a message is available
public.subscribe(func);
let unsubscribe = public.subscribe(func);
server.send("Hello World");
// Unsubscribe using the returned function from subscribe
unsubscribe();
// OR
// This will unsubscribe the function. Please note, that it can
// only unsubscribe the exact function, that is used in subscribe
public.unsubscribe(func);
@ -56,6 +61,44 @@ Usage:
server.send("Hello World2");
```
## AwaitStore
This component can be used to await a specific value or to act as an variable with events.
Usage:
``` typescript
import { AwaitStore } from "@hibas123/util";
const server = new AwaitStore<number>(0); // Set initial value
// Server can send and subscribe to messages
// Only receiving is possible using the public API
const public = server.getPublicApi();
const func = (data)=>{
console.log(data);
}
// awaitValue will also return a .ignore() function, that can be used to abort the promise completely
public.awaitValue(5).then(()=>console.log("Got 5"));
// func will be callen when a message is available and once with the current value
// This will call func with the current value (0) and on every change after.
public.subscribe(func);
// This send will trigger the subscribtion func and also release the awaitValue causing "Got 5"
// to appear in the console
server.send(5);
// This will unsubscribe the function. Please note, that it can
// only unsubscribe the exact function, that is used in subscribe
public.unsubscribe(func);
// This now won't call func anymore
server.send(8);
```
## License
MIT

78
src/awaiter.ts Normal file
View File

@ -0,0 +1,78 @@
import Observable, { ObserverCallback } from "./observable";
export default class AwaitStore<T = any> {
private observable = new Observable<T>();
constructor(private _value: T) {
this.subscribe = this.subscribe.bind(this);
this.unsubscribe = this.unsubscribe.bind(this);
}
get value() {
return this._value;
}
send(value: T) {
this._value = value;
this.observable.send(value);
}
subscribe(handler: ObserverCallback<T>) {
handler(this._value);
this.observable.subscribe(handler);
return () => this.unsubscribe(handler);
}
unsubscribe(handler: ObserverCallback<T>) {
this.observable.unsubscribe(handler);
}
awaitValue(val: T): PromiseLike<void> & { catch: (cb: (err: any) => PromiseLike<void>) => PromiseLike<void>, ignore: () => void } {
let ignore: () => void;
let prms = new Promise<void>(yes => {
const cb = () => {
if (this._value === val) {
yes();
this.observable.unsubscribe(cb);
return true;
}
return false
}
ignore = () => {
this.observable.unsubscribe(cb);
}
if (!cb()) {
this.observable.subscribe(cb);
}
});
return {
then: prms.then.bind(prms),
catch: prms.catch.bind(prms),
ignore: () => ignore()
}
}
/**
* Creates Public API with subscribe and unsubscribe
*
* @returns {object}
*/
getPublicApi() {
if (this.observable.closed)
throw new Error("Observable is closed!");
return {
subscribe: (callback: ObserverCallback<T>) => this.subscribe(callback),
unsubscribe: (callback: ObserverCallback<T>) => this.unsubscribe(callback),
awaitValue: (value: T) => this.awaitValue(value)
}
}
close() {
this.observable.close();
}
}

View File

@ -1,5 +1,6 @@
import Lock, { Release } from "./lock";
import Observable, { ObserverCallback, ObserverCallbackCollect, ObservableInterface } from "./observable";
import AwaitStore from "./awaiter";
export {
Lock,
@ -7,5 +8,6 @@ export {
Observable,
ObserverCallback,
ObserverCallbackCollect,
ObservableInterface
ObservableInterface,
AwaitStore
}

View File

@ -43,6 +43,8 @@ export default class Observable<T = any> {
let oldcb = this.subscriber.find(e => e === callback);
if (!oldcb)
this.subscriber.push(callback)
return () => this.unsubscribe(callback);
}
unsubscribe(callback: ObserverCallback<T> | ObserverCallbackCollect<T>) {