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 🙏

© 2024 – Pkg Stats / Ryan Hefner

poll

v3.2.2

Published

A simple poll function based on async, await, and an infinite loop

Downloads

20,218

Readme

poll

A simple poll function based on async, await, and an infinite loop.

Features:

  • Asynchronous callback function
  • Delay function to customize the polling interval (e.g. to implement exponential backoff)
  • Cancellation function to stop polling altogether (e.g. stop polling after 10 cycles or once a certain condition is fulfilled)

Links:

Contents

Installation & usage

As npm package

  1. Install the poll package.

    npm install poll
  2. Import the poll function and use it.

    // “poll” is mapped to “poll/dist/poll.js” by Node.js via the package’s “exports” field.
    import { poll } from 'poll'
    
    function fn() {
    	console.log('Hello, beautiful!')
    }
    
    poll(fn, 1000)

As plain JS file

  1. Download the poll module.

    curl -O 'https://cdn.jsdelivr.net/npm/poll@latest/dist/poll.js'
  2. Import the poll function and use it.

    <script type="module">
    	import { poll } from './poll.js'
    
    	function fn() {
    		console.log('Hello, beautiful!')
    	}
    
    	poll(fn, 1000)
    </script>

Documentation

Syntax

poll(function, delay[, shouldStopPolling])

Parameters:

  • Name: fn Type: () => any Required: Yes Description: A function to be called every delay milliseconds. No parameters are passed to fn upon calling it.

  • Name: delayOrDelayCallback Type: number | (() => number) Required: Yes Description: The delay (in milliseconds) to wait before calling the function fn again. If a function is provided instead of a number, it is evaluated during every polling cycle right before the wait period. If the delay is a negative number, zero will be used instead.

  • Name: shouldStopPolling Type: () => boolean | Promise<boolean> Required: No Default: () => false Description: A function (or a promise resolving to a function) indicating whether to stop the polling process by returning a truthy value (e.g. true). The shouldStopPolling callback function is called twice during one polling cycle:

    • After the result of the call to fn was successfully awaited (right before triggering a new delay period).
    • After the delay has passed (right before calling fn again).

    This guarantees two things:

    • A currently active execution of fn will be completed.
    • No new calls to fn will be triggered.

Return value:

None.

Examples

Minimal

The poll function expects two parameters: A callback function and a delay. After calling poll with these parameters, the callback function will be called. After it’s done being executed, the poll function will wait for the specified delay. After the delay, the process starts from the beginning.

const pollDelayInMinutes = 10

async function getStatusUpdates() {
	const pokemonId = Math.floor(Math.random() * 151 + 1)
	const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}/`)
	const pokemon = await response.json()
	console.log(pokemon.name)
}

poll(getStatusUpdates, pollDelayInMinutes * 60 * 1000)

Note that poll will not cause a second call to the callback function if the first call is never finishing. For example, if the endpoint /status does not respond and the server doesn’t time out the connection, poll will still be waiting for the callback function to resolve until the dusk of time.

Stop polling

You can pass a callback function to poll for its third parameter. It’s evaluated before and after calls to the polled function. If it evaluates to a truthy value, the poll function’s loop will stop and the function returns.

let stopPolling = false
const shouldStopPolling = () => stopPolling

function fn() {
	console.log('Hello, beautiful!')
}

setTimeout(() => {
	stopPolling = true
}, 1000)

poll(fn, 50, shouldStopPolling)

In this example, the shouldStopPolling callback function evaluates to true after the setTimeout function causes stopPolling to be set to true after 1000 milliseconds. The next time shouldStopPolling is evaluated, it will cause poll to exit normally.

Stop polling using asynchronous shouldStopPolling function

You can also provide an asynchronous function for the shouldStopPolling callback function.

let stopPolling = false
const shouldStopPolling = () => new Promise((resolve) => {
	setTimeout(() => {
		resolve(stopPolling)
	}, 100)
})

function fn() {
	console.log('Hello, beautiful!')
}

setTimeout(() => {
	stopPolling = true
}, 1000)

poll(fn, 50, shouldStopPolling)

Beware that this function will be called twice per polling cycle.

Exponential backoff: increase polling interval with every cycle

By providing a function that returns the delay value instead of the delay value itself, you can customize the behavior of the polling interval. In the following example, the delay doubles with each polling cycle.

const pollDelayInMinutes = 1
let delay = pollDelayInMinutes * 60 * 1000

const startTime = Date.now()

async function getStatusUpdates() {
	const pokemonId = Math.floor(Math.random() * 151 + 1)
	const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}/`)
	const pokemon = await response.json()
	const seconds = (Date.now() - startTime) / 1000
	console.log('Seconds passed:', seconds, pokemon.name)
}

const delayCallback = () => {
	const currentDelay = delay
	delay *= 2
	return currentDelay
}

poll(getStatusUpdates, delayCallback)

Versioning

This package uses semantic versioning.

Update package version

  1. Make some changes and run the tests and the build script.

    npm test
    npm run build
  2. Commit the changes.

  3. Verify that you’re authenticated with npm.

    npm whomai

    If you’re not authenticated, do so using npm login.

  4. Change the package’s version locally.

    # See `npm version --help` for more options
    npm version minor

    This changes the version number in the package.json file and adds a new git tag matching the new version.

  5. Push your changes and the updated git tags separately.

    git push
    git push --tags
  6. Publish the package.

    npm publish