Skip to content

Instantly share code, notes, and snippets.

@jimbuck
Created November 30, 2021 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimbuck/60db5d9e24cfdb6b161076af995ca3be to your computer and use it in GitHub Desktop.
Save jimbuck/60db5d9e24cfdb6b161076af995ca3be to your computer and use it in GitHub Desktop.
Creates a buffered function using RXJS.
import { Subject, fromEvent } from 'rxjs';
import { buffer, map, filter } from 'rxjs/operators';
function buffered<T>(handler: ((values: T[]) => Promise<void>)) {
const valueQueue = new Subject<T>();
const bufferTrigger = new Subject<void>();
let busy = false;
let destroyed = false;
const sub = valueQueue.pipe(
buffer(bufferTrigger),
filter(values => !!values?.length)
).subscribe(async (values) => {
if (destroyed) return;
busy = true;
await handler(values);
busy = false;
bufferTrigger.next();
})
function next(value: T) {
if (destroyed) return;
valueQueue.next(value);
if (!busy) bufferTrigger.next();
}
next.close = () => {
sub.unsubscribe();
destroyed = true;
}
return next;
}
console.clear();
const wheel$ = fromEvent(document, 'wheel').pipe(map(e => (e as any).deltaY as number));
const scroll = buffered(async (values: number[]) => {
const total = values.reduce((acc, val) => acc + val, 0);
console.log(`Scrolls: ${values}, Total: ${total}`);
await move(total);
});
wheel$.subscribe(amount => scroll(amount))
async function move(amount: number) {
amount = Math.abs(amount);
await delay(amount + Math.random() * amount);
}
function delay(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment