A simple solution to a classic problem: setInterval implemented as recursive setTimeout calls.
This package is designed to be a drop-in replacement for the normal setInterval.
Take a look at this section from javascript.info, it outlines the problem and the solution.
Basically, the normal setInterval doesn't wait for the callback to happen, – it schedules the next iteration right away:
functionrunsForOneSecond(){conststartTime=Date.now()while(Date.now()-startTime<1000){/* just wait */}console.log(Date.now(),'Done!')}console.log(Date.now(),'Start')setInterval(runsForOneSecond,500)// logs (approximately):// 1234567890000 Start// 1234567891500 Done!// 1234567892500 Done!// 1234567893500 Done!… while the "recursive timeout" approach necessarily waits for the callback to finish before scheduling the next call:
import{setRecursive}from'recursive-timeout'console.log(Date.now(),'Start')setRecursive(runsForOneSecond,500)// logs (approximately):// 1234567890000 Start// 1234567891500 Done!// 1234567893000 Done!// 1234567894500 Done!- Dual Module Support: Works seamlessly with both ECMAScript Modules (
import) and CommonJS (require). - Familiar API: Designed as a drop-in replacement for
setInterval. - Promise-based API:
⚠️ (coming soon)⚠️ A promise-based interface for use with asynchronous callbacks.
npm install recursive-timeoutThe straightforward API of setRecursive and clearRecursive mirrors the native setInterval and clearInterval functions.
This is the standard way to use the package, ideal for most cases.
import{setRecursive,clearRecursive}from'recursive-timeout'setRecursive(()=>console.log('hi'),1000)setRecursive(console.log,1000,'hi')To cancel the interval, pass the timer into clearRecursive or the standard clearInterval, or even clearTimeout:
constrecursive=setRecursive(console.log,1000,'hi')clearRecursive(recursive)clearInterval(recursive)// ✅ worksclearTimeout(recursive)// ✅ also worksFor TypeScript users, some additional checks are added:
functionsum(a: number,b: number): void{console.log(a+b)}setRecursive(sum,100)// ❌ Error: not enough argumentssetRecursive(sum,100,42)// ❌ Error: not enough argumentssetRecursive(sum,100,42,17)// ✅ OK (logs 59 every ~100 milliseconds)import{setRecursive,clearRecursive}from'recursive-timeout/promises'import{promises}from'recursive-timeout'promises.setRecursive(…)promises.clearRecursive(…)const{ setRecursive, clearRecursive }=require('recursive-timeout')const{ setRecursive, clearRecursive }=require('recursive-timeout/promises')const{ promises }=require('recursive-timeout')promises.setRecursive(…)promises.clearRecursive(…)This project is licensed under the MIT License.