Skip to content

Instantly share code, notes, and snippets.

@tracker1
Last active September 16, 2018 14:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tracker1/fb103312c276a585bdfa4565427692cb to your computer and use it in GitHub Desktop.
Save tracker1/fb103312c276a585bdfa4565427692cb to your computer and use it in GitHub Desktop.
Async Generator Stream debounce in JS
// for reference:
// https://www.bignerdranch.com/blog/asyncing-feeling-about-javascript-generators/
// https://gist.github.com/nybblr/3af62797052c42f7090b4f8614b5e157#gistcomment-2044311
const destreamify = async (stream, callback) => {
for await (let event of stream) {
callback(event);
}
};
// Note, will not pass when event === undefined
const debounce = function*(stream, interval) {
let first; // is this first event? will pass
let lastEvent; // the last event raised
let deferred; // deferred promise instance
let resolve; // resolve method for deferred promise
// reset internal state - create new deferred/resolve
const reset = (isFirst) => {
first = isFirst;
lastEvent = undefined;
deferred = new Promise(r => resolve = r);
};
// handle event resolution
const passEvent = () => {
// if no event to pass
if (lastEvent === undefined) {
first = true; // reset first state
return;
}
const event = lastEvent; // handle to event to pass
const res = resolve; // handle to resolve for current deferred
reset(false); // reset and create next deferred
setTimeout(passEvent, interval); // debounce timer
res(event); // resolve current deferred
};
reset(true); // set initial state & deferred
destreamify(stream, (event) => {
lastEvent = event; // reference event
if (first) passEvent(); // if first run, pass it through
});
// yield deferred results
while (true) {
yield deferred;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment