Skip to content

Instantly share code, notes, and snippets.

@IZEDx
Created March 15, 2018 05:42
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 IZEDx/8bafc86ca9f45295559c73817019d2fa to your computer and use it in GitHub Desktop.
Save IZEDx/8bafc86ca9f45295559c73817019d2fa to your computer and use it in GitHub Desktop.
Demonstration of using setImmediate() and async/await-syntax to program recursively without exceeding the maximum call stack size and tail call optimizations
/**
* Adds the passed function to the JavaScript Message Queue to be executed by the Event Loop,
* wraps a Promise around that and resolves any asynchronous values.
* This allows to call a function asynchronously and on the Event Loop, which doesn't grow the call stack,
* but can be used in a synchronous manner using await.
* @param fn The function to be executed, can be async.
* @param args The arguments to be passed to this function.
*/
function immediate<T, K>(fn: (...args: K[]) => T|Promise<T>, ...args: K[]) {
return new Promise<T>(res => {
setImmediate(() => {
const t = fn(...args);
if (t instanceof Promise) {
t.then(res);
} else {
res(t);
}
});
});
}
/**
* Recursive implementation of the Fibonacci Sequence.
* Makes the callstack grow.
* @param n Iterations to calculate.
* @returns {[number, number]} Tuple containing the result of n and n-1 iterations.
*/
function fibRecusive(n: number): [number, number] {
if (n <= 1) return [1, 1];
const [n1, n2] = fibRecusive(n - 1); // Stack trace is a bitch
return [n1 + n2, n1];
}
/**
* Asynchronous recursive implementation of the Fibonacci Sequence, using immediate wrapper.
* Works recursive but does not add to the callstack.
* @param n Iterations to calculate.
* @returns {[number, number]} Tuple containing the result of n and n-1 iterations.
*/
async function fibImmediate(n: number): Promise<[number, number]> {
if (n <= 1) return [1, 1];
const [n1, n2] = await immediate(fibImmediate, n - 1); // Async for the rescue
return [n1 + n2, n1];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment