En su columna CodeSOD, Remy Porter relata cómo Karen, una desarrolladora encargada de mantener pruebas de especificación en TypeScript, rastreó una inestabilidad rara pero persistente. Las pruebas funcionales basadas en especificaciones fallaban aproximadamente tres o cuatro veces por cada mil ejecuciones, mientras que las pruebas unitarias seguían pasando. Las operaciones eran sensibles al tiempo, y las pruebas ya utilizaban ventanas de tiempo generosas, por lo que la fuente de la inestabilidad no era evidente.
En varios puntos, las pruebas necesitaban esperar al menos dos milisegundos. La función auxiliar original era el one-liner idiomático:
```typescript export const wait = (ms:number) => new Promise((complete) => setTimeout(complete, ms)); ```
La documentación estándar de JavaScript advierte que `setTimeout` puede esperar más tiempo del solicitado, lo cual Karen aceptaba. Sin embargo, la documentación de Node.js no garantiza cuándo se invoca el callback, lo que significa que el temporizador puede dispararse antes de que transcurra el tiempo.
Tras muchas horas de depuración, Karen descubrió que esos disparos prematuros eran exactamente la causa de los fallos. Reemplazó la función auxiliar simple por esta versión de sondeo:
```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); }); } ```
Esta verifica la hora cada milisegundo y solo resuelve la promesa cuando el tiempo objetivo realmente ha transcurrido. El cambio estabiliza las pruebas, pero el autor señala que este workaround es lamentable: existe solo porque Node.js incumple la garantía de programación que otros runtimes suelen respetar: esperar al menos el tiempo solicitado, aunque posiblemente mucho más.