npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

repeat-function-call-timer

v1.0.7

Published

Repeat or retry a function call until it returns a specific value or a timeout is reached

Readme

Repeat function-call timer

Repeat or retry a function call until it returns a specific value or a timeout is reached.

Created for handling / observing intermediate or final states of asynchronous processes (see Details), but also helpful for other things (see Examples).

hh lohmann <[email protected]>

Synopsis

  import { repeatFunctionCallTimer } from 'repeat-function-call-timer'

  repeatFunctionCallTimer( functionToCall, expectedValue, timeout, interval )

  await repeatFunctionCallTimer( functionToCall, expectedValue, timeout, interval )

  const res = await repeatFunctionCallTimer( functionToCall, expectedValue, timeout, interval )
  if(res.match) ...

  repeatFunctionCallTimer( functionToCall, expectedValue, timeout, interval )
  .then(res=>{
    if(res.match){ ... }
    else{ ... }
  })

  repeatFunctionCallTimer( functionToCall, expectedValue, timeout, interval, whenInterval )

Parameters

functionToCall

Function to repeat

  • Returning a target value that allows matching expectedValue to exit repetition
    • Use no or an intentionally unmatchable return to exit on timeout only
  • Intentionally left to be defined in detail by individual use cases to gain maximum flexibility
  • Intentionally no parameters
    • Parameters may introduce complexity that might not be easy to control
    • You may use whenInterval to manipulate an external environment at runtime to be listened to by functionToCall
  • Can not be an asynchronous function / Promise or a function returning an asynchronous function / Promise since it runs synchronously to points in time resulting from defined interval, but is intended to be usable as an observer for asynchronous functions / Promises (see Details / Examples)

expectedValue

Value to compare with return of functionToCall to exit repetition

  • Can only be a Primitive Type (except Symbol), i.e. null or of type bigint / boolean / number / string / undefined
    • For working with Arrays, Errors, Functions, Objects, Maps or RegExps you would use a wrapper functionToCall with an own comparison method returning true or false
  • Use an intentionally unmatchable value to exit on timeout only

timeout

Timespan in milliseconds to repeat functionToCall to match expectedValue before giving up

  • Use no or an intentionally unmatchable return of functionToCall or an intentionally unmatchable value to exit on timeout only

interval

Timespan in milliseconds to wait before next repetition

whenInterval

optional: Callback on start of new interval

  • Hook for injecting actions
  • Parameter: passedTime: The time passed since start. May be used for analyses.
  • Note: Does not allow to manipulate internal parameters at runtime, but you may manipulate an external environment to be listened to by functionToCall

Returns

  • Promise that resolves to an object with properties "match" and passedTime" => see Examples

Examples

As observer

  • Do something only if an observed process set a value

      function observerFunction(){
        // ... code to check if observed value has been set by observed process ...
        if(observedValueHasBeenSet) return true;
        return false;
      }
      const res = await repeatFunctionCallTimer( observerFunction, true, 2000, 100 )
      if(res.match){ // ... something only if value was set in given time }
  • Do different things depending if another asynchronous process set a value

      function observerFunction(){
        // ... code to check if observed value has been set by observed process ...
        if(observedValueHasBeenSet) return true;
        return false;
      }
      repeatFunctionCallTimer( observerFunction, true, 2000, 100 )
      .then(res=>{
        if(res.match){ // ... something only if value was set in given time }
        else{ // ... something if value was no set in given time }
      })
  • Tracking an observed process that sets trackable values

      function observerFunction(){
        // ... code to check current values set by observed process ...
        if(observedValue==='reading') return console.log('Reading data...');
        if(observedValue==='processing') return console.log('Processing data...');
        if(observedValue==='writing') return console.log('Writing data...');
        if(observedValue==='fail') return 'finished';
        if(observedValue==='success') return 'finished';
        return 'unknown';
      }
      const res = await repeatFunctionCallTimer( observerFunction, 'finished', 2000, 100 )
      .then(res=>{
        if(res.match){ console.log(`Process XY finished - see XY's own output for details`) }
        else{ console.log(`Process XY did not finish in expected time`) }
      })

For plain repetition

  • Log current time's seconds while doing something else

      repeatFunctionCallTimer( ()=>console.log(new Date().getSeconds()), '', 3000, 1000 );
      // ... meanwhile something else ...
  • Log current time's seconds before doing something else

      await repeatFunctionCallTimer( ()=>console.log(new Date().getSeconds()), '', 3000, 1000 );
      // ... afterwards something else ...

Demos

See demos

Caveats

  • Be aware that timers in JavaScript are not exact, depending e.g. on the current Call stack. They are reliable for "normal" checking and ordering, but not for high precision orchestration which is clearly not the scope here

  • The functionToCall itself can not be an asynchronous function / Promise or a function returning an asynchronous function / Promise since it runs synchronously to points in time resulting from defined interval, but is intended to be usable as an observer for asynchronous functions / Promises (see Examples)

Installation

Pick for your preferred package manager:

  npm i repeat-function-call-timer
  pnpm i repeat-function-call-timer
  bun i repeat-function-call-timer
  # For Yarn you should double check docs for your and / or
  # current Yarn version, newer versions do not treat `i package_name`
  # as an alias for `add ...` and exclude global installations
  yarn add repeat-function-call-timer

Details

  • Created primarily for handling / observing intermediate or final states of asynchronous processes, especially when there is no resolving to be handled with await or .then(), but the possibility to write to a variable that can be observed by a simple functionToCall. If then() / await is available, the defined timeout can intercept if a then() / await that would set the observed variable takes too long. Using separatetly started processes communicating via an observed variable instead of e.g. one process starting another process for observing it should guarantee simplicity, flexibility and robustness.

  • Besides observing other processes (see above) also usable for plain repetition of an arbitrary function until an arbitrary expectedValue is matched

  • Intentionally no parameter for "number of tries" / "maximum number of tries": Such parameters are dangerous without a timeout, otherwise you might wait forever (or until a system timeout) for a try without an answer, but you can always model a number of e.g. 10 tries by setting timeout as the 10th of interval

  • Implemented as a recursion of setTimeout calls that is terminated by timeout or matching expectedValue

Tests

  • Code tests to be run with Node.js / Bun available in Source Code

Source Code

References

MDN: await
MDN: Call Stack
MDN: Primitive Types (JavaScript)
MDN: Recursion
MDN: resolve
MDN: setTimeout
MDN: thenables
MDN: Using promises
MDN: Working with asynchronous functions