p-throttle
Advanced tools
+34
-18
@@ -11,5 +11,5 @@ declare class AbortErrorClass extends Error { | ||
| declare namespace pThrottle { | ||
| type ThrottledFunction<Arguments extends unknown[], Return> = (( | ||
| ...arguments: Arguments | ||
| ) => Promise<Return>) & { | ||
| type ThrottledFunction<FunctionType extends (...args: any) => any> = (( | ||
| ...arguments: Parameters<FunctionType> | ||
| ) => ReturnType<FunctionType>) & { | ||
| /** | ||
@@ -21,14 +21,32 @@ Abort pending executions. All unresolved promises are rejected with a `pThrottle.AbortError` error. | ||
| interface Options { | ||
| /** | ||
| Maximum number of calls within an `interval`. | ||
| */ | ||
| limit: number; | ||
| /** | ||
| Timespan for `limit` in milliseconds. | ||
| */ | ||
| interval: number; | ||
| } | ||
| type AbortError = AbortErrorClass; | ||
| /** | ||
| @param fn - Promise-returning/async function or a normal function. | ||
| */ | ||
| type Throttle<FunctionType extends (...args: any) => any> = (fn: (...arguments: Parameters<FunctionType>) => ReturnType<FunctionType>) => ThrottledFunction<FunctionType>; | ||
| } | ||
| declare const pThrottle: { | ||
| AbortError: typeof AbortErrorClass; | ||
| /** | ||
| [Throttle](https://css-tricks.com/debouncing-throttling-explained-examples/) promise-returning/async/normal functions. | ||
| @param fn - Promise-returning/async function or a normal function. | ||
| @param limit - Maximum number of calls within an `interval`. | ||
| @param interval - Timespan for `limit` in milliseconds. | ||
| @returns A throttled version of `fn`. | ||
| Both the `limit` and `interval` options must be specified. | ||
| @example | ||
@@ -38,5 +56,10 @@ ``` | ||
| const throttled = pThrottle(async index => { | ||
| const throttle = pThrottle({ | ||
| limit: 2, | ||
| interval: 1000 | ||
| }); | ||
| const throttled = throttle(async index => { | ||
| return index * 2; | ||
| }, 2, 1000); | ||
| }); | ||
@@ -48,14 +71,7 @@ for (let i = 1; i <= 6; i++) { | ||
| */ | ||
| <Arguments extends unknown[], Return>( | ||
| fn: (...arguments: Arguments) => PromiseLike<Return> | Return, | ||
| limit: number, | ||
| interval: number | ||
| ): pThrottle.ThrottledFunction<Arguments, Return>; | ||
| AbortError: typeof AbortErrorClass; | ||
| // TODO: Remove this for the next major release | ||
| default: typeof pThrottle; | ||
| <FunctionType extends (...args: any) => any>( | ||
| options: pThrottle.Options | ||
| ): pThrottle.Throttle<FunctionType>; | ||
| }; | ||
| export = pThrottle; |
+32
-32
@@ -10,3 +10,3 @@ 'use strict'; | ||
| const pThrottle = (fn, limit, interval) => { | ||
| const pThrottle = ({limit, interval}) => { | ||
| if (!Number.isFinite(limit)) { | ||
@@ -25,43 +25,43 @@ throw new TypeError('Expected `limit` to be a finite number'); | ||
| const throttled = function (...args) { | ||
| let timeout; | ||
| return new Promise((resolve, reject) => { | ||
| const execute = () => { | ||
| resolve(fn.apply(this, args)); | ||
| queue.delete(timeout); | ||
| }; | ||
| return function_ => { | ||
| const throttled = function (...args) { | ||
| let timeout; | ||
| return new Promise((resolve, reject) => { | ||
| const execute = () => { | ||
| resolve(function_.apply(this, args)); | ||
| queue.delete(timeout); | ||
| }; | ||
| const now = Date.now(); | ||
| const now = Date.now(); | ||
| if ((now - currentTick) > interval) { | ||
| activeCount = 1; | ||
| currentTick = now; | ||
| } else if (activeCount < limit) { | ||
| activeCount++; | ||
| } else { | ||
| currentTick += interval; | ||
| activeCount = 1; | ||
| } | ||
| if ((now - currentTick) > interval) { | ||
| activeCount = 1; | ||
| currentTick = now; | ||
| } else if (activeCount < limit) { | ||
| activeCount++; | ||
| } else { | ||
| currentTick += interval; | ||
| activeCount = 1; | ||
| } | ||
| timeout = setTimeout(execute, currentTick - now); | ||
| timeout = setTimeout(execute, currentTick - now); | ||
| queue.set(timeout, reject); | ||
| }); | ||
| }; | ||
| queue.set(timeout, reject); | ||
| }); | ||
| }; | ||
| throttled.abort = () => { | ||
| for (const timeout of queue.keys()) { | ||
| clearTimeout(timeout); | ||
| queue.get(timeout)(new AbortError()); | ||
| } | ||
| throttled.abort = () => { | ||
| for (const timeout of queue.keys()) { | ||
| clearTimeout(timeout); | ||
| queue.get(timeout)(new AbortError()); | ||
| } | ||
| queue.clear(); | ||
| queue.clear(); | ||
| }; | ||
| return throttled; | ||
| }; | ||
| return throttled; | ||
| }; | ||
| module.exports = pThrottle; | ||
| // TODO: Remove this for the next major release | ||
| module.exports.default = pThrottle; | ||
| module.exports.AbortError = AbortError; |
+10
-9
| { | ||
| "name": "p-throttle", | ||
| "version": "3.1.0", | ||
| "version": "4.0.0", | ||
| "description": "Throttle promise-returning & async functions", | ||
| "license": "MIT", | ||
| "repository": "sindresorhus/p-throttle", | ||
| "funding": "https://github.com/sponsors/sindresorhus", | ||
| "author": { | ||
| "name": "Sindre Sorhus", | ||
| "email": "sindresorhus@gmail.com", | ||
| "url": "sindresorhus.com" | ||
| "url": "https://sindresorhus.com" | ||
| }, | ||
| "engines": { | ||
| "node": ">=6" | ||
| "node": ">=10" | ||
| }, | ||
@@ -43,9 +44,9 @@ "scripts": { | ||
| "devDependencies": { | ||
| "ava": "^1.4.1", | ||
| "delay": "^4.1.0", | ||
| "in-range": "^1.0.0", | ||
| "time-span": "^2.0.0", | ||
| "tsd": "^0.7.2", | ||
| "xo": "^0.24.0" | ||
| "ava": "^2.4.0", | ||
| "delay": "^4.4.0", | ||
| "in-range": "^2.0.0", | ||
| "time-span": "^4.0.0", | ||
| "tsd": "^0.14.0", | ||
| "xo": "^0.37.1" | ||
| } | ||
| } |
+25
-19
@@ -1,2 +0,2 @@ | ||
| # p-throttle [](https://travis-ci.org/sindresorhus/p-throttle) | ||
| # p-throttle | ||
@@ -9,3 +9,2 @@ > [Throttle](https://css-tricks.com/debouncing-throttling-explained-examples/) promise-returning & async functions | ||
| ## Install | ||
@@ -17,6 +16,5 @@ | ||
| ## Usage | ||
| Here, the trottled function is only called twice a second: | ||
| Here, the throttled function is only called twice a second: | ||
@@ -28,6 +26,11 @@ ```js | ||
| const throttled = pThrottle(index => { | ||
| const throttle = pThrottle({ | ||
| limit: 2, | ||
| interval: 1000 | ||
| }); | ||
| const throttled = throttle(index => { | ||
| const secDiff = ((Date.now() - now) / 1000).toFixed(); | ||
| return Promise.resolve(`${index}: ${secDiff}s`); | ||
| }, 2, 1000); | ||
| }); | ||
@@ -45,16 +48,17 @@ for (let i = 1; i <= 6; i++) { | ||
| ## API | ||
| ### pThrottle(fn, limit, interval) | ||
| ### pThrottle(options) | ||
| Returns a `throttle` function. | ||
| Returns a throttled version of `fn`. | ||
| #### fn | ||
| #### options | ||
| Type: `Function` | ||
| Type: `object` | ||
| Promise-returning/async function or a normal function. | ||
| Both the `limit` and `interval` options must be specified. | ||
| #### limit | ||
| ##### limit | ||
@@ -65,3 +69,3 @@ Type: `number` | ||
| #### interval | ||
| ##### interval | ||
@@ -72,2 +76,10 @@ Type: `number` | ||
| ### throttle(function_) | ||
| #### function_ | ||
| Type: `Function` | ||
| Promise-returning/async function or a normal function. | ||
| ### throttledFn.abort() | ||
@@ -77,3 +89,2 @@ | ||
| ## Related | ||
@@ -85,6 +96,1 @@ | ||
| - [More…](https://github.com/sindresorhus/promise-fun) | ||
| ## License | ||
| MIT © [Sindre Sorhus](https://sindresorhus.com) |
Sorry, the diff of this file is not supported yet
6708
4.29%109
12.37%89
7.23%