2.0 kB · 89 lines · Created 1y ago
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990const sleep = (ms: number): Promise<void> => { return new Promise((resolve) => setTimeout(resolve, ms));};
type MaybePromise<T> = T | Promise<T>;
type TaskFunction<TArgs extends unknown[], TReturn> = ( ...args: { [K in keyof TArgs]: MaybePromise<TArgs[K]> }) => Promise<TReturn>;
const task = <TArgs extends unknown[], TReturn>( fn: (...args: TArgs) => Promise<TReturn>): TaskFunction<TArgs, TReturn> => { return async (...args) => { const resolved = await Promise.all(args); resolved satisfies TArgs; return await fn(...resolved); };};
type SerialFunction<TArgs extends unknown[], TReturn> = ( ...args: TArgs) => Promise<TReturn>;
const serial = <TArgs extends unknown[], TReturn>( fn: (...args: TArgs) => Promise<TReturn>): SerialFunction<TArgs, TReturn> => { let held: Promise<void> | undefined;
return async (...args) => { const { promise, resolve } = Promise.withResolvers<void>(); const previous = held;
held = promise; await previous;
try { return await fn(...args); } finally { resolve(); } };};
const e = task(async (a: number, c: number, d: number) => { await sleep(10); console.log("e: computing", a, "*", c, "*", d); return a * c * d;});
const d = task(async (b: number) => { await sleep(1); console.log("d: computing", b, "* 2"); return b * 2;});
const c = task(async (a: number, b: number) => { await sleep(5); console.log("c: computing", a, "+", b); return a + b;});
const a = task(async (n1: number, n2: number, n3: number) => { await sleep(15); console.log("a: computing", n1, "+", n2, "+", n3); return n1 + n2 + n3;});
const b = task(async (n1: number, n2: number, n3: number) => { await sleep(10); console.log("b: computing", n1, "+", n2, "+", n3); return n1 + n2 + n3;});
{ const tA = a(4, 2, 3); const tB = b(4, 2, 3);
const tC = c(tA, tB); const tD = d(tB);
const tE = e(tA, tC, tD);
const result = await tE;
console.log(result);}
export {};