typescript / expert
Snippet
Extern gesteuerte Promises mit Promise.withResolvers
Promise.withResolvers (ES2024, TS 5.4+) liefert das Promise zusammen mit seinen resolve- und reject-Funktionen, ohne dass du sie im Executor-Callback einfangen musst. Das umgeht das hässliche 'let resolve!; new Promise(r => { resolve = r; })'-Deferred-Pattern und erlaubt Cancellation-Tokens, Semaphoren oder ereignisgesteuerte Gates, die von außerhalb des Konstruktor-Scopes aufgelöst werden. Der typisierte Generic-Parameter erhält die Form des aufgelösten Werts, und ein Wrapper wie createGate fügt Idempotenz hinzu — entscheidend, wenn mehrere Aufrufer um dieselbe Future konkurrieren.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function createGate<T>() {const { promise, resolve, reject } = Promise.withResolvers<T>();let settled = false;return {promise,open(value: T) {if (settled) return;settled = true;resolve(value);},fail(err: unknown) {if (settled) return;settled = true;reject(err);},};}const gate = createGate<number>();setTimeout(() => gate.open(42), 100);const value = await gate.promise; // 42
Erklärung
1
const { promise, resolve, reject } = Promise.withResolvers<T>();
Destrukturiert das Trio in einem Aufruf — kein Deferred-Boilerplate mehr.
2
let settled = false;
Lokales Flag erzwingt Idempotenz, sodass ein zweiter open/fail-Aufruf wirkungslos bleibt.
3
open(value: T) { if (settled) return; settled = true; resolve(value); }
Löst das Promise extern genau einmal auf, auch bei konkurrierenden Aufrufern.
4
const value = await gate.promise;
Die Konsumentenseite awaitet wie gewohnt; für den Aufrufer ändert sich nichts.