GithubHelp home page GithubHelp logo

jcoreio / async-throttle Goto Github PK

View Code? Open in Web Editor NEW
17.0 4.0 1.0 1.89 MB

throttle async and promise-returning functions like lodash.throttle

License: MIT License

JavaScript 96.69% TypeScript 3.31%
async-await async throttle promise

async-throttle's Introduction

async-throttle

CircleCI codecov semantic-release Commitizen friendly npm version

Throttle async and promise returning functions. Unlike similarly named packages, this behaves much like an async version of lodash.throttle:

  • Only one invocation can be running at a time (similarly named packages don't do this)
  • Has .cancel() and .flush()

Differences from lodash.throttle

  • No leading and trailing options
  • getNextArgs option allows you to customize how the arguments for the next invocation are determined

Installing

npm install --save @jcoreio/async-throttle

Usage

const throttle = require('@jcoreio/async-throttle')
import throttle from '@jcoreio/async-throttle'
function throttle<Args: Array<any>, Value>(
  func: (...args: Args) => Promise<Value>,
  wait: ?number,
  options?: {
    getNextArgs?: (current: Args, next: Args) => Args
  }
): (...args: Args) => Promise<Value>;

Creates a throttled function that only invokes func at most once per every wait milliseconds, and also waits for the Promise returned by the previous invocation to finish (it won't invoke func in parallel).

The promise returned by the throttled function will track the promise returned by the next invocation of func.

If wait is falsy, it is treated as 0, which causes func to be invoked on the next tick afte the previous invocation finishes.

By default, func is called with the most recent arguments to the throttled function. You can change this with the getNextArgs option -- for example, if you want to invoke func with the minimum of all arguments since the last invocation:

const throttledFn = throttle(foo, 10, {
  getNextArgs: ([a], [b]) => [Math.min(a, b)],
})
throttledFn(2)
throttledFn(1)
throttledFn(3)
// foo will be called with 1

// time passes...

throttledFn(4)
throttledFn(6)
throttledFn(5)
// foo will be called with 4

throttledFn.invokeIgnoreResult(args)

Calls the throttled function soon, but doesn't return a promise, catches any CanceledError, and doesn't create any new promises if a call is already pending.

To use this, you should handle all errors inside the throttled function:

const throttled = throttle(async (arg) => {
  try {
    await doSomething(arg)
  } catch (err) {
    // handle error
  }
})

Then call invokeIgnoreResult instead of the throttled function:

throttled.invokeIgnoreResult(arg)

The invokeIgnoreResult method is useful because the following code example would leave 1000 pending promises on the heap, even though the catch block is a no-op:

for (let i = 0; i < 1000; i++) {
  throttled(arg).catch(() => {})
}

throttledFn.cancel()

Cancels the pending invocation, if any. All Promises tracking the pending invocation will be rejected with a CancelationError (const {CancelationError} = require('@jcoreio/async-throttle')). However, if an invocation is currently running, all Promises tracking the current invocation will be fulfilled as usual.

Returns a Promise that will resolve once the current invocation (if any) is finished.

throttledFn.flush()

Cancels the wait before the pending invocation, if any. The pending invocation will still wait for the current invocation (if any) to finish, but will begin immediately afterward, even if wait has not elapsed.

Returns a Promise that will resolve once the current invocation (if any) is finished.

async-throttle's People

Contributors

greenkeeper[bot] avatar jedwards1211 avatar jrmclaurin avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

miracle2k

async-throttle's Issues

Describe 'Other packages don't do it right.'

I'm guessing what you're getting at is you can end up with uncaught promise exceptions... or is there something else too?

Would be good to explain properly what this package does that others don't. At present I have no idea if it will solve my problem without digging through your source code

Exporting a `.d.ts` file?

Hello,

I was wondering if you could expose a .d.ts file, this should be generatable from your flow typings.

Add cancel/abort.

Similarly to lodash, it would be awesome to have a cancel method attached to the returned function.

The implemention would cancel any pending timeout as well as returning a the ongoing promise, so that it can be awaited.

Confusing example in readme

Shoudn't:

const throttled = throttle(foo, 10, {
  getNextArgs: ([a], [b]) => [Math.min(a, b)]
})
throttled(2)
throttled(1)
throttled(3)
// foo will be called with 1

// time passes...

throttled(4)
throttled(6)
throttled(5)
// foo will be called with 4

be:

const throttled = throttle(foo, 10, {
  getNextArgs: ([a], [b]) => [Math.min(a, b)]
})
throttled(1)
throttled(2)
throttled(3)
// foo will be called with 3

// time passes...

throttled(4)
throttled(5)
throttled(6)
// foo will be called with 6

?

Remove Babel requirement?

Hey again :)

I recently switched to the official npm module, but since Babel isn't used server-side in this case, I get errors like

  <rejected> Error: Cannot find module 'babel-runtime/regenerator'
  Require stack:
  - C:\Users\Me\AppData\Roaming\npm\node_modules\karaoke-forever\node_modules\@jcoreio\async-throttle\lib\index.js
  - C:\Users\Me\AppData\Roaming\npm\node_modules\karaoke-forever\server\Library\ipc.js
  - C:\Users\Me\AppData\Roaming\npm\node_modules\karaoke-forever\server\serverWorker.js
  - C:\Users\Me\AppData\Roaming\npm\node_modules\karaoke-forever\server\main.js
      at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
      at Function.Module._load (internal/modules/cjs/loader.js:841:27)
      at Module.require (internal/modules/cjs/loader.js:1025:19)
      at require (internal/modules/cjs/helpers.js:72:18)
      at Object.<anonymous> (C:\Users\Me\AppData\Roaming\npm\node_modules\karaoke-forever\node_modules\@jcoreio\async-throttle\lib\index.js:3:20)
      at Module._compile (internal/modules/cjs/loader.js:1137:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
      at Module.load (internal/modules/cjs/loader.js:985:32)
      at Function.Module._load (internal/modules/cjs/loader.js:878:14)
      at Module.require (internal/modules/cjs/loader.js:1025:19) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
      'C:\\Users\\Me\\AppData\\Roaming\\npm\\node_modules\\karaoke-forever\\node_modules\\@jcoreio\\async-throttle\\lib\\index.js',
      'C:\\Users\\Me\\AppData\\Roaming\\npm\\node_modules\\karaoke-forever\\server\\Library\\ipc.js',
      'C:\\Users\\Me\\AppData\\Roaming\\npm\\node_modules\\karaoke-forever\\server\\serverWorker.js',
      'C:\\Users\\Me\\AppData\\Roaming\\npm\\node_modules\\karaoke-forever\\server\\main.js'
    ]

FWIW, the src works fine as-is in modern Node versions (minus the type annotations of course) but I'm not sure of other ramifications. Thanks again for this library!

result.catch is not a function

Hi again,

Starting with 1.3.0 I'm getting this error with each throttled call:

  <rejected> TypeError: result.catch is not a function
      at invoke (.../node_modules/@jcoreio/async-throttle/index.js:100:31)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

My usage hasn't changed and 1.2.0 and earlier work fine... maybe a check just needs to be added there? Thanks for taking a look!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.