task.ts
edited
1const sleep = (ms: number): Promise<void> => {
2 return new Promise((resolve) => setTimeout(resolve, ms));
3};
4
5type MaybePromise<T> = T | Promise<T>;
6
7type TaskFunction<TArgs extends unknown[], TReturn> = (
8 ...args: { [K in keyof TArgs]: MaybePromise<TArgs[K]> }
9) => Promise<TReturn>;
10
11const task = <TArgs extends unknown[], TReturn>(
12 fn: (...args: TArgs) => Promise<TReturn>
13): TaskFunction<TArgs, TReturn> => {
14 return async (...args) => {
15 const resolved = await Promise.all(args);
16 resolved satisfies TArgs;
17 return await fn(...resolved);
18 };
19};
20
21type SerialFunction<TArgs extends unknown[], TReturn> = (
22 ...args: TArgs
23) => Promise<TReturn>;
24
25const serial = <TArgs extends unknown[], TReturn>(
26 fn: (...args: TArgs) => Promise<TReturn>
27): SerialFunction<TArgs, TReturn> => {
28 let held: Promise<void> | undefined;
29
30 return async (...args) => {
31 const { promise, resolve } = Promise.withResolvers<void>();
32 const previous = held;
33
34 held = promise;
35 await previous;
36
37 try {
38 return await fn(...args);
39 } finally {
40 resolve();
41 }
42 };
43};
44
45const e = task(async (a: number, c: number, d: number) => {
46 await sleep(10);
47 console.log("e: computing", a, "*", c, "*", d);
48 return a * c * d;
49});
50
51const d = task(async (b: number) => {
52 await sleep(1);
53 console.log("d: computing", b, "* 2");
54 return b * 2;
55});
56
57const c = task(async (a: number, b: number) => {
58 await sleep(5);
59 console.log("c: computing", a, "+", b);
60 return a + b;
61});
62
63const a = task(async (n1: number, n2: number, n3: number) => {
64 await sleep(15);
65 console.log("a: computing", n1, "+", n2, "+", n3);
66 return n1 + n2 + n3;
67});
68
69const b = task(async (n1: number, n2: number, n3: number) => {
70 await sleep(10);
71 console.log("b: computing", n1, "+", n2, "+", n3);
72 return n1 + n2 + n3;
73});
74
75{
76 const tA = a(4, 2, 3);
77 const tB = b(4, 2, 3);
78
79 const tC = c(tA, tB);
80 const tD = d(tB);
81
82 const tE = e(tA, tC, tD);
83
84 const result = await tE;
85
86 console.log(result);
87}
88
89export {};