Skip to content

Instantly share code, notes, and snippets.

@xxzefgh
Last active February 15, 2021 10:10
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 xxzefgh/ef374ef8fe89d578fee19335be49ed7b to your computer and use it in GitHub Desktop.
Save xxzefgh/ef374ef8fe89d578fee19335be49ed7b to your computer and use it in GitHub Desktop.
interface ReduceResult<T> {
done: true;
value: T;
}
export function reduceLargeArray<T, R>(
arr: T[],
processEachFn: (acc: R, x: T) => ReduceResult<R> | R,
initialValue: R,
onCompleteFn: (r: R) => void
) {
let frameTime = 1000 / 60; // 60 FPS
let accumulator = initialValue;
function isDone<T>(value: unknown): value is ReduceResult<T> {
return value && value['done'];
}
function nextBatch(start: number) {
let tstart = Date.now();
for (let i = start; i < arr.length; i++) {
let tdelta = Date.now() - tstart;
if (tdelta >= frameTime) {
requestAnimationFrame(() => nextBatch(i));
break;
}
let resultOrDone = processEachFn(accumulator, arr[i]);
if (isDone(resultOrDone)) {
onCompleteFn(resultOrDone.value);
break;
} else if (i === arr.length - 1) {
onCompleteFn(resultOrDone);
break;
}
accumulator = resultOrDone;
}
}
if (arr.length === 0) {
onCompleteFn(accumulator);
} else {
nextBatch(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment