async function loopWithDelay({ doWhat, stopWhen, minInterval }) {
while (!stopWhen()) {
const interval = startInterval(minInterval);
await doWhat();
const ms = await interval();
console.log(`resumed after ${ms}ms...`);
}
console.log("finished.");
}
await loopWithDelay({
doWhat: doSomethingForMs(150),
stopWhen: stopAfterMs(2000),
minInterval: 500
});
// a simple delay helper (in every single codebase :)
function delay(ms) {
return new Promise(r => setTimeout(r, ms)); }
// a higher-order helper to calculate a timelapse
function startTimeLapse() {
const startTime = Date.now();
return () => Date.now() - startTime;
}
// a higher-order helper for a minimal interval delay
function startInterval(ms) {
const sinceStarted = startTimeLapse();
return () => {
const sinceDelayed = startTimeLapse();
return delay(Math.max(ms - sinceStarted(), 0)).then(sinceDelayed);
};
}
// a higher-order helper to simulate an asynchronous task
function doSomethingForMs(ms) {
let count = 0;
return async () => {
const elapsed = startTimeLapse();
await delay(ms); // simulate an asynchronous task
console.log(`done something for the ${++count} time, it took ${elapsed()}ms`);
}
}
// a higher-order helper to tell when to stop
function stopAfterMs(ms) {
const elapsed = startTimeLapse();
return () => elapsed() > ms;
}