async-deco
Advanced tools
Comparing version 5.1.8 to 6.0.0
{ | ||
"name": "async-deco", | ||
"version": "5.1.8", | ||
"version": "6.0.0", | ||
"description": "A collection of decorators for adding features to asynchronous functions (callback or promise based).", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
214
README.md
@@ -21,2 +21,6 @@ async-deco | ||
* [Dedupe](#dedupe) | ||
* [parallel](#parallel) | ||
* [waterfall](#waterfall) | ||
* [race](#race) | ||
* [balance](#balance) | ||
@@ -330,2 +334,141 @@ Callback and promises | ||
Parallel | ||
-------- | ||
"parallel" executes every function in parallel. If a function returns an error the execution stops immediatly returning the error. | ||
The functions will get the same arguments and the result will be an array of all the results. | ||
```js | ||
var parallel = require('async-deco/callback/parallel'); | ||
var func = parallel([ | ||
function (x, cb) { | ||
cb(null, x + 1); | ||
}, | ||
function (x, cb) { | ||
cb(null, x + 2); | ||
} | ||
]); | ||
func(3, function (err, values) { | ||
// values contains [4, 5] | ||
}); | ||
``` | ||
Waterfall | ||
--------- | ||
"waterfall" executes the functions in series. The first function will get the arguments and the others will use the arguments passed by the previous one: | ||
```js | ||
var waterfall = require('async-deco/callback/waterfall'); | ||
var func = waterfall([ | ||
function (x, cb) { | ||
cb(null, x + ' world'); | ||
}, | ||
function (x, cb) { | ||
cb(null, x + '!'); | ||
} | ||
]); | ||
func('hello', function (err, value) { | ||
// value === 'hello world!' | ||
}); | ||
``` | ||
Race | ||
---- | ||
"race" will execute all functions in parallel but it will return the first valid result. | ||
```js | ||
var race = require('async-deco/callback/race'); | ||
var func = race([ | ||
function (x, cb) { | ||
setTimeout(function () { | ||
cb(null, x + 1); | ||
}, 20) | ||
}, | ||
function (x, cb) { | ||
setTimeout(function () { | ||
cb(null, x + 2); | ||
}, 10) | ||
} | ||
]); | ||
func(3, function (err, values) { | ||
// values contains 5 (fastest) | ||
}); | ||
``` | ||
Parallel - Waterfall - Race | ||
--------------------------- | ||
It is very easy to combine these functions to create a more complex flow: | ||
```js | ||
var func = waterfall([ | ||
parallel([ | ||
function (x, cb) { | ||
cb(null, x * 2); | ||
}, | ||
function (x, cb) { | ||
cb(null, x * 3); | ||
} | ||
]), | ||
function (numbers, cb) { | ||
cb(null, numbers.reduce(function (acc, item) { | ||
return acc + item; | ||
}, 0)); | ||
}, | ||
function (x, cb) { | ||
cb(null, x - 5); | ||
} | ||
]); | ||
func(5, function (err, value) { | ||
// value === 20; | ||
}); | ||
``` | ||
Although these functions are also available for promise, I suggest to use the native promise API, unless you have a better reason for doing differently. | ||
* parallel: Promise.all | ||
* race: Promise.race | ||
* waterfall: just chain different promises | ||
Balance | ||
------- | ||
This decorator allows to distribute the load between a group of functions. | ||
The functions should take the same arguments. | ||
```js | ||
var balance = require('async-deco/callback/balance'); | ||
var balanceDecorator = balance(); | ||
var func = balanceDecorator([...list of functions]); | ||
func(...args, function (err, res) { | ||
// ... | ||
}); | ||
``` | ||
You can initialise the decorator with different policies: | ||
```js | ||
var balance = require('async-deco/callback/balance'); | ||
var balancePolicies = require('async-deco/utils/balance-policies'); | ||
var balanceDecorator = balance(balancePolicies.roundRobin); | ||
... | ||
``` | ||
There are 3 policies available in the "balance-policies" package: | ||
* roundRobin: it rotates the execution between the functions | ||
* random: it picks up a random function | ||
* idlest (default): it tracks the load of each function and use the idlest | ||
You can also define your own policy: | ||
```js | ||
var balance = require('async-deco/callback/balance'); | ||
var balanceDecorator = balance(function (counter, loads) { | ||
// "counter2 is the number of times I have called the function | ||
// "loads" is an array with length equal to the number of functions | ||
// it contains how many calls are currently running for that function | ||
// this function should return the index of the function I want to run | ||
}); | ||
... | ||
``` | ||
Utilities | ||
@@ -434,63 +577,2 @@ ========= | ||
Parallel - Waterfall - Race | ||
--------------------------- | ||
These special utilities can be used to manage the execution of a group of functions (callback based). | ||
"parallel" executes every function in parallel. If a function returns an error the execution stops immediatly returning the error. | ||
The functions will get the same arguments and the result will be an array of all the results. | ||
```js | ||
var func = parallel([ | ||
function (x, cb) { | ||
cb(null, x + 1); | ||
}, | ||
function (x, cb) { | ||
cb(null, x + 2); | ||
} | ||
]); | ||
func(3, function (err, values) { | ||
// values contains [4, 5] | ||
}); | ||
``` | ||
"waterfall" executes the functions in series. The first function will get the arguments and the others will use the arguments passed by the previous one: | ||
```js | ||
var func = waterfall([ | ||
function (x, cb) { | ||
cb(null, x + ' world'); | ||
}, | ||
function (x, cb) { | ||
cb(null, x + '!'); | ||
} | ||
]); | ||
func('hello', function (err, value) { | ||
// value === 'hello world!' | ||
}); | ||
``` | ||
"race" will execute all functions in parallel but it will return the first valid result. | ||
It is very easy to combine these functions to create a more complex flow: | ||
```js | ||
var func = waterfall([ | ||
parallel([ | ||
function (x, cb) { | ||
cb(null, x * 2); | ||
}, | ||
function (x, cb) { | ||
cb(null, x * 3); | ||
} | ||
]), | ||
function (numbers, cb) { | ||
cb(null, numbers.reduce(function (acc, item) { | ||
return acc + item; | ||
}, 0)); | ||
}, | ||
function (x, cb) { | ||
cb(null, x - 5); | ||
} | ||
]); | ||
func(5, function (err, value) { | ||
// value === 20; | ||
}); | ||
``` | ||
Examples and use cases | ||
@@ -533,1 +615,11 @@ ====================== | ||
``` | ||
Queue | ||
----- | ||
In some case you may want to preserve the sequence used to call a function. For example, sending commands to a db being sure they are executed in the right order. | ||
```js | ||
var limitDecorator = require('async-deco/callback/limit'); | ||
var queue = limitDecorator(1); | ||
var myfunc = queue(function (..., cb) { .... }); | ||
``` |
var promisify = require('es6-promisify'); | ||
var callbackify = require('../utils/callbackify'); | ||
// it works for decorator(f) and decorator([f1, f2, f3 ...]) | ||
function promiseTranslator(decorator) { | ||
return function (f) { // f returns a promise | ||
return promisify(decorator(callbackify(f))); | ||
var cb; | ||
if (Array.isArray(f)) { | ||
cb = f.map(callbackify); | ||
} else { | ||
cb = callbackify(f); | ||
} | ||
return promisify(decorator(cb)); | ||
}; | ||
@@ -8,0 +17,0 @@ } |
@@ -10,3 +10,3 @@ | ||
for (var i = fns.length - 1; i > -1; i--) { | ||
if(!fns[i]) continue; | ||
if (!fns[i]) continue; | ||
result = fns[i].call(this, result); | ||
@@ -13,0 +13,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
115488
105
3108
622