Skip to content

Instantly share code, notes, and snippets.

@4skinSkywalker
Created October 2, 2021 15:57
Show Gist options
  • Save 4skinSkywalker/4648f2d76ee2f35be964998b7506f44c to your computer and use it in GitHub Desktop.
Save 4skinSkywalker/4648f2d76ee2f35be964998b7506f44c to your computer and use it in GitHub Desktop.
This two snippets mimic what BehaviorSubject and Subject do (as I use them)
/* The objective of the two following snippets is to
* handle async events with an imperative style of
* coding
*
* I also want the API to be compatible with that of
* observables, so that I can drop-in replace them
* That means it should also work with "| async"
* in Angular
*
* By convention use $ as suffix to mark the varname
* (so that you know it's a special var)
*
* I want a AsyncVar to:
* - Sets some data
* - Remembers the data
* - Can be listened for changes
* - Can stop being listened
*/
export function AsyncVar(value = undefined) {
this.value = value;
this.consumers = {};
}
AsyncVar.prototype.set = function(value) {
this.value = value;
for (let key in this.consumers) {
this.consumers[key](value); // Should I use hasOwnProperty?
}
};
AsyncVar.prototype.next = AsyncVar.prototype.set;
AsyncVar.prototype.get = function() {
return this.value;
};
AsyncVar.prototype.getValue = AsyncVar.prototype.get;
AsyncVar.prototype.sub = function(callback) {
// This is necessary for "| async" in Angular
if ("next" in callback) {
callback = callback.next;
}
// Run it with last value
callback(this.value);
// This is a kind of unique id
let namespace = Math.random().toString(36).slice(2);
this.consumers[namespace] = callback;
let usub = () => {
delete this.consumers[namespace];
};
return {
usub,
unsubscribe: usub
};
}
AsyncVar.prototype.subscribe = AsyncVar.prototype.sub;
/*
* I want an AsyncPulse that:
* - Sends some data (but doesn't remember it)
* - Can be listened for changes
* - Can stop being listened
*/
export function AsyncPulse() {
this.consumers = {};
}
AsyncPulse.prototype.set = function(value) {
for (let key in this.consumers) {
this.consumers[key](value); // Should I use hasOwnProperty?
}
};
AsyncPulse.prototype.next = AsyncPulse.prototype.set;
AsyncPulse.prototype.sub = function(callback) {
// This is necessary for "| async" in Angular
if ("next" in callback) {
callback = callback.next;
}
// This is a kind of unique id
let namespace = Math.random().toString(36).slice(2);
this.consumers[namespace] = callback;
let usub = () => {
delete this.consumers[namespace];
};
return {
usub,
unsubscribe: usub
};
}
AsyncPulse.prototype.subscribe = AsyncPulse.prototype.sub;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment