https://github.com/tomeraberbach/limit-concur
⚖️ Limit an async function's concurrency with ease!
https://github.com/tomeraberbach/limit-concur
async concurrency javascript nodejs npm-module npm-package promise rate-limiting
Last synced: 9 months ago
JSON representation
⚖️ Limit an async function's concurrency with ease!
- Host: GitHub
- URL: https://github.com/tomeraberbach/limit-concur
- Owner: TomerAberbach
- License: apache-2.0
- Created: 2021-04-04T02:56:44.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2025-09-01T20:37:13.000Z (10 months ago)
- Last Synced: 2025-09-06T13:58:58.052Z (10 months ago)
- Topics: async, concurrency, javascript, nodejs, npm-module, npm-package, promise, rate-limiting
- Language: TypeScript
- Homepage: https://npm.im/limit-concur
- Size: 521 KB
- Stars: 23
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- Contributing: contributing.md
- License: license
Awesome Lists containing this project
README
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
```sh
$ npm i limit-concur
```
## Usage
```js
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`](https://github.com/sindresorhus/p-map)
```js
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`](https://github.com/sindresorhus/p-all)
```js
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`](https://github.com/sindresorhus/p-limit)
```js
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`](https://github.com/sindresorhus/p-filter)
```js
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`](https://github.com/sindresorhus/p-props)
```js
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](https://github.com/TomerAberbach/limit-concur/issues/new).
## License
[MIT](https://github.com/TomerAberbach/limit-concur/blob/main/license-mit) ©
[Tomer Aberbach](https://github.com/TomerAberbach) \
[Apache 2.0](https://github.com/TomerAberbach/limit-concur/blob/main/license-apache) ©
[Google](https://github.com/TomerAberbach/limit-concur/blob/main/notice-apache)