133 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Async-Limiter
 | 
						|
 | 
						|
A module for limiting concurrent asynchronous actions in flight. Forked from [queue](https://github.com/jessetane/queue).
 | 
						|
 | 
						|
[](http://www.npmjs.org/async-limiter)
 | 
						|
[](https://travis-ci.org/STRML/async-limiter)
 | 
						|
[](https://coveralls.io/r/STRML/async-limiter)
 | 
						|
 | 
						|
This module exports a class `Limiter` that implements some of the `Array` API.
 | 
						|
Pass async functions (ones that accept a callback or return a promise) to an instance's additive array methods.
 | 
						|
 | 
						|
## Motivation
 | 
						|
 | 
						|
Certain functions, like `zlib`, have [undesirable behavior](https://github.com/nodejs/node/issues/8871#issuecomment-250915913) when
 | 
						|
run at infinite concurrency.
 | 
						|
 | 
						|
In this case, it is actually faster, and takes far less memory, to limit concurrency.
 | 
						|
 | 
						|
This module should do the absolute minimum work necessary to queue up functions. PRs are welcome that would
 | 
						|
make this module faster or lighter, but new functionality is not desired.
 | 
						|
 | 
						|
Style should confirm to nodejs/node style.
 | 
						|
 | 
						|
## Example
 | 
						|
 | 
						|
``` javascript
 | 
						|
var Limiter = require('async-limiter')
 | 
						|
 | 
						|
var t = new Limiter({concurrency: 2});
 | 
						|
var results = []
 | 
						|
 | 
						|
// add jobs using the familiar Array API
 | 
						|
t.push(function (cb) {
 | 
						|
  results.push('two')
 | 
						|
  cb()
 | 
						|
})
 | 
						|
 | 
						|
t.push(
 | 
						|
  function (cb) {
 | 
						|
    results.push('four')
 | 
						|
    cb()
 | 
						|
  },
 | 
						|
  function (cb) {
 | 
						|
    results.push('five')
 | 
						|
    cb()
 | 
						|
  }
 | 
						|
)
 | 
						|
 | 
						|
t.unshift(function (cb) {
 | 
						|
  results.push('one')
 | 
						|
  cb()
 | 
						|
})
 | 
						|
 | 
						|
t.splice(2, 0, function (cb) {
 | 
						|
  results.push('three')
 | 
						|
  cb()
 | 
						|
})
 | 
						|
 | 
						|
// Jobs run automatically. If you want a callback when all are done,
 | 
						|
// call 'onDone()'.
 | 
						|
t.onDone(function () {
 | 
						|
  console.log('all done:', results)
 | 
						|
})
 | 
						|
```
 | 
						|
 | 
						|
## Zlib Example
 | 
						|
 | 
						|
```js
 | 
						|
const zlib = require('zlib');
 | 
						|
const Limiter = require('async-limiter');
 | 
						|
 | 
						|
const message = {some: "data"};
 | 
						|
const payload = new Buffer(JSON.stringify(message));
 | 
						|
 | 
						|
// Try with different concurrency values to see how this actually
 | 
						|
// slows significantly with higher concurrency!
 | 
						|
//
 | 
						|
// 5:        1398.607ms
 | 
						|
// 10:       1375.668ms
 | 
						|
// Infinity: 4423.300ms
 | 
						|
//
 | 
						|
const t = new Limiter({concurrency: 5});
 | 
						|
function deflate(payload, cb) {
 | 
						|
  t.push(function(done) {
 | 
						|
    zlib.deflate(payload, function(err, buffer) {
 | 
						|
      done();
 | 
						|
      cb(err, buffer);
 | 
						|
    });
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
console.time('deflate');
 | 
						|
for(let i = 0; i < 30000; ++i) {
 | 
						|
  deflate(payload, function (err, buffer) {});
 | 
						|
}
 | 
						|
q.onDone(function() {
 | 
						|
  console.timeEnd('deflate');
 | 
						|
});
 | 
						|
```
 | 
						|
 | 
						|
## Install
 | 
						|
 | 
						|
`npm install async-limiter`
 | 
						|
 | 
						|
## Test
 | 
						|
 | 
						|
`npm test`
 | 
						|
 | 
						|
## API
 | 
						|
 | 
						|
### `var t = new Limiter([opts])`
 | 
						|
Constructor. `opts` may contain inital values for:
 | 
						|
* `q.concurrency`
 | 
						|
 | 
						|
## Instance methods
 | 
						|
 | 
						|
### `q.onDone(fn)`
 | 
						|
`fn` will be called once and only once, when the queue is empty.
 | 
						|
 | 
						|
## Instance methods mixed in from `Array`
 | 
						|
Mozilla has docs on how these methods work [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).
 | 
						|
### `q.push(element1, ..., elementN)`
 | 
						|
### `q.unshift(element1, ..., elementN)`
 | 
						|
### `q.splice(index , howMany[, element1[, ...[, elementN]]])`
 | 
						|
 | 
						|
## Properties
 | 
						|
### `q.concurrency`
 | 
						|
Max number of jobs the queue should process concurrently, defaults to `Infinity`.
 | 
						|
 | 
						|
### `q.length`
 | 
						|
Jobs pending + jobs to process (readonly).
 | 
						|
 |