In seiner CodeSOD-Kolumne erzählt Remy Porter, wie Karen, eine Entwicklerin, die TypeScript-Spezifikationstests betreute, eine seltene, aber hartnäckige Instabilität aufspürte. Die funktionalen, spezifikationsbasierten Tests schlugen etwa drei- bis viermal bei jeder tausendsten Ausführung fehl, während die Unit-Tests durchweg bestanden. Die Operationen waren zeitabhängig, und die Tests nutzten bereits großzügige Zeitfenster, weshalb die Ursache nicht auf der Hand lag.
An mehreren Stellen mussten die Tests mindestens zwei Millisekunden warten. Die ursprüngliche Hilfsfunktion war der idiomatische Einzeiler:
```typescript export const wait = (ms:number) => new Promise((complete) => setTimeout(complete, ms)); ```
Die Standard-JavaScript-Dokumentation warnt, dass `setTimeout` länger als angefordert warten kann, was Karen akzeptierte. Die Node.js-Dokumentation jedoch gibt keine Garantie, wann der Callback aufgerufen wird, sodass der Timer sogar vor Ablauf der Zeit auslösen kann.
Nach längerer Fehlersuche stellte Karen fest, dass genau diese vorzeitigen Auslösungen die Fehler verursachten. Sie ersetzte die einfache Hilfsfunktion durch diese pollende Version:
```typescript export const wait = (ms: number) { const target = performance.now() + ms; return new Promise((complete) => { const checkReady = () => { if (performance.now() > target) { complete(); } else { setTimeout(checkReady, 1); } } setTimeout(checkReady, 1); }); } ```
Diese prüft jede Millisekunde die Zeit und löst die Promise erst auf, wenn die Zielzeit tatsächlich erreicht ist. Die Änderung stabilisiert die Tests, aber der Autor merkt an, dass dieser Workaround bedauerlich ist: Er existiert nur, weil Node.js die übliche Planungsgarantie anderer Runtimes verletzt – mindestens so lange wie angefordert zu warten, wenn auch möglicherweise deutlich länger.
Kommentare
Noch keine Kommentare — schreib den ersten.
Starte die Diskussion
Kein Konto, kein Passwort nötig — gib einfach deine E-Mail-Adresse ein, wir senden dir einen einmaligen Anmelde-Link. Beim ersten Mal bist du damit automatisch angemeldet.
Deine Bewertung wird nach der Anmeldung automatisch übernommen.
Schau in dein Postfach
Wir haben einen Anmelde-Link an … gesendet. Öffne ihn auf diesem Gerät — dieser Tab meldet dich automatisch an.
Nichts angekommen? Wirf einen Blick in den Spam-Ordner — und markiere die Mail dort als „Kein Spam“, dann landet sie künftig direkt im Postfach.