Skip to content

Commit e8bebf3

Browse files
authored
🚧 wip generator generation post
1 parent 1baa18f commit e8bebf3

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: Generator Generation
3+
published: false
4+
subtitle: 16 December 2025
5+
description: Converting callback based APIs into Async Generators
6+
---
7+
8+
```ts
9+
function sleep() {
10+
return new Promise((res) => setTimeout(res, 1000));
11+
}
12+
13+
function withResolvers<T>() {
14+
let resolve: (v: T) => void = () => undefined;
15+
let reject: (error: unknown) => void = () => undefined;
16+
let done = false;
17+
18+
const promise = new Promise<T>((res, rej) => {
19+
resolve = res;
20+
reject = rej;
21+
});
22+
23+
return {
24+
promise,
25+
resolve(v: T) {
26+
resolve(v);
27+
done = true;
28+
},
29+
reject(err: unknown) {
30+
reject(err);
31+
done = true;
32+
},
33+
get done() {
34+
return done;
35+
},
36+
};
37+
}
38+
39+
function createGenerator<T, R>() {
40+
let current = withResolvers<T>();
41+
let final = withResolvers<R>();
42+
43+
const generator: AsyncGenerator<T, R> = {
44+
[Symbol.asyncIterator]() {
45+
return generator;
46+
},
47+
48+
async return() {
49+
const value = await final.promise;
50+
51+
return { done: true, value };
52+
},
53+
54+
async next() {
55+
if (final.done) {
56+
const value = await final.promise;
57+
return {
58+
done: true,
59+
value,
60+
};
61+
}
62+
63+
const value = await current.promise;
64+
return {
65+
done: false,
66+
value,
67+
};
68+
},
69+
throw(e) {
70+
throw e;
71+
},
72+
};
73+
74+
const next = (value: T) => {
75+
current.resolve(value);
76+
if (!final.done) {
77+
current = withResolvers();
78+
}
79+
};
80+
81+
const done = (result: R) => {
82+
final.resolve(result);
83+
};
84+
85+
return {
86+
next,
87+
done,
88+
generator,
89+
};
90+
}
91+
92+
function myCallbackFunction(
93+
onResult: (value: number) => void,
94+
onDone: () => void,
95+
) {
96+
setTimeout(() => onResult(1), 1000);
97+
setTimeout(() => onResult(2), 2000);
98+
setTimeout(() => onResult(3), 3000);
99+
setTimeout(onDone, 4000);
100+
}
101+
102+
async function main() {
103+
const { done, generator, next } = createGenerator<number, void>();
104+
105+
myCallbackFunction(next, done);
106+
107+
for await (const value of generator) {
108+
console.log(value);
109+
}
110+
}
111+
112+
main();
113+
```

0 commit comments

Comments
 (0)