Skip to content

⚖️ Limit an async function's concurrency with ease!

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
license-apache
MIT
license-mit
Notifications You must be signed in to change notification settings

TomerAberbach/limit-concur

Repository files navigation

limit-concur

Limit an async function's concurrency with ease!

Features

  • Tiny: only ~300 B minzipped
  • Flexible: works for any function that returns a Promise

Install

$ npm i limit-concur

Usage

import limitConcur from 'limit-concur'

const categories = await (
  await fetch(`https://api.chucknorris.io/jokes/categories`)
).json()

let pendingRequests = 0
const getChuckNorrisJoke = async category => {
  console.log(`pending requests: ${++pendingRequests}`)
  const response = await fetch(
    `https://api.chucknorris.io/jokes/random?category=${encodeURIComponent(category)}`,
  )
  const { value } = await response.json()
  console.log(`pending requests: ${--pendingRequests}`)
  return value
}

const limitedGetChuckNorrisJoke = limitConcur(4, getChuckNorrisJoke)

// At most 4 requests are pending at any given time!
const jokes = await Promise.all(categories.map(limitedGetChuckNorrisJoke))
console.log(jokes)
//=> pending requests: 1
//=> pending requests: 2
//=> pending requests: 3
//=> pending requests: 4
//=> pending requests: 3
//=> pending requests: 4
//=> ...
//=> pending requests: 3
//=> pending requests: 2
//=> pending requests: 1
//=> pending requests: 0
//=> [
//     'Chuck Norris once rode a nine foot grizzly bear through an automatic car wash, instead of taking a shower.',
//     "Chuck Norris is actually the front man for Apple. He let's Steve Jobs run the show when he's on a mission. Chuck Norris is always on a mission.",
//     "Bill Gates thinks he's Chuck Norris. Chuck Norris actually laughed. Once.",
//     'Chuck Norris can install iTunes without installing Quicktime.',
//     ...
//   ]

Recipes

Replacing p-map

import limitConcur from 'limit-concur'

const urls = [`https://tomeraberba.ch`, `https://lfi.dev`, `https://npmjs.com`]

const mapper = async url => {
  const { redirected } = await fetch(url, { method: `head` })
  return redirected
}

const results = await Promise.all(urls.map(limitConcur(2, mapper)))
console.log(results)
//=> [ false, false, true ]

Replacing p-all

import limitConcur from 'limit-concur'

const actions = [
  () => fetch(`https://tomeraberba.ch`),
  () => fetch(`https://lfi.dev`),
  () => checkSomething(),
  () => doSomethingElse(),
]

const results = await Promise.all(
  actions.map(limitConcur(2, action => action())),
)
console.log(results)
//=> [ ..., ..., ... ]

Replacing p-limit

import limitConcur from 'limit-concur'

const limit = limitConcur(1, fn => fn())

const input = [
  limit(() => fetchSomething(`foo`)),
  limit(() => fetchSomething(`bar`)),
  limit(() => doSomething()),
]

const results = await Promise.all(input)
console.log(results)
//=> [ ..., ..., ... ]

Replacing p-filter

import limitConcur from 'limit-concur'

const urls = [`https://tomeraberba.ch`, `https://lfi.dev`, `https://npmjs.com`]

const filterer = async url => {
  const { redirected } = await fetch(url, { method: `head` })
  return !redirected
}

const results = await Promise.all(
  urls.map(limitConcur(2, async url => ({ url, keep: await filterer(url) }))),
)
const filtered = results.flatMap(({ url, keep }) => (keep ? [url] : []))
console.log(filtered)
//=> [ 'https://tomeraberba.ch', 'https://lfi.dev' ]

Replacing p-props

import limitConcur from 'limit-concur'

const urls = {
  tomer: `https://tomeraberba.ch`,
  lfi: `https://lfi.dev`,
  npm: `https://npmjs.com`,
}

const mapper = async url => {
  const { redirected } = await fetch(url, { method: `head` })
  return redirected
}

const results = Object.fromEntries(
  await Promise.all(
    Object.entries(urls).map(
      limitConcur(2, async ([name, url]) => [name, await mapper(url)]),
    ),
  ),
)
console.log(results)
//=> { tomer: false, lfi: false, npm: true }

Contributing

Stars are always welcome!

For bugs and feature requests, please create an issue.

License

MIT © Tomer Aberbach
Apache 2.0 © Google

About

⚖️ Limit an async function's concurrency with ease!

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
license-apache
MIT
license-mit

Stars

Watchers

Forks

Sponsor this project