promise-mix
v1.8.4
Published
Node module with some useful Promise composition functionalities.
Downloads
34
Maintainers
Readme
Promise Mix
This module contains a lot of extensions to default Node.js Promise.
Check out the full A-Z list of extensions!
How?
Install
~$ npm install promise-mix
Import
To use the extensions, simply import the module in your script:
require('promise-mix');
or
import 'promise-mix';
Why?
While using promises I often find it hard to orchestrate them correctly and in an elegant, readable way.
Thus I decided to make some extension to the basic Promise
library in order to put some order in my code.
For example, when having to return a structured JSON composed with the results of different Promise
I'd usually just build a Promise
chain like this:
Promise.resolve('first promise result')
.then((res1) => {
return Promise.resolve('second promise result')
.then((res2) => {
return { res1, res2 };
});
})
.then((res12) => {
return Promise.resolve('third promise result')
.then((res3) => {
return {...res12, res3};
});
})
.then((output) => {
res.send(output)
}).catch(next);
/**
* this would return to the caller:
*
* {
* res1: 'first promise result',
* res2: 'second promise result',
* res3: 'third promise result'
* }
* /
With the aggregate
extension, it'd be much more straight forward and clean to obtain the same result:
Promise.aggregate({
res1: Promise.resolve('first promise result'),
res2: Promise.resolve('second promise result'),
res3: Promise.resolve('third promise result'),
})
.then((output) => {
res.send(output)
}).catch(next);
// this would return the same output as above.
Check out all the extensions for more useful combination methods.
What?
This module adds four basic composition functions to the basic Promise
Object:
aggregate
puts the results of a series of Promise into an aggregate object and passes it downstream as a single promise result.Promise.aggregate({ cats: Promise.resolve(['Felix', 'Garfield']), dogs: Promise.resolve(['Rex', 'Lessie']), turtles: Promise.resolve([]), fish: Promise.resolve('Nemo') }) .then(({ cats, dogs, fish, turtle }) => { // { cats, dogs, fish, turtle } = { cats: ['Felix', 'Garfield'], dogs: ['Rex', 'Lessie'], fish: 'Nemo', turtle: [] } });
compose
likeaggregate
, but each item of the input must be a function returning a Promise. Results from previous promises will be passed down as parameters to successive functions:Promise.combine({ cats: () => { return Promise.resolve(['Felix', 'Garfield'])), dogs: ({ cats }) => { return Promise.resolve(['Rex', 'Lessie']) }, turtles: ({ cats, dogs }) => { return Promise.resolve([]) }, fish: ({ cats, dogs, turtle }) => { return Promise.resolve('Nemo') }, everyone: ({ cats, dogs, turtle, fish }) => { return Promise.resolve({ cats, dogs, turtle, fish }) } }) .then(({ cats, dogs, fish, turtle, everyone }) => { // { cats, dogs, fish, turtle, everyone } = { cats: ['Felix', 'Garfield'], dogs: ['Rex', 'Lessie'], fish: 'Nemo', turtle: [], everyone: { cats: ['Felix', 'Garfield'], dogs: ['Rex', 'Lessie'], fish: 'Nemo', turtle: [] } } });
merge
merges the results of an array of promises into a single flat array:Promise.merge([ Promise.resolve(['Felix', 'Garfield']), Promise.resolve(['Rex', 'Lessie']), Promise.resolve([]), Promise.resolve(['Nemo']) ]) .then((results) => { // results = ['Felix', 'Garfield', 'Rex', 'Lessie', 'Nemo'] });
reduce
accepts an array of functions returning promises and returns the result of the last promise in the array. Each promise result is passed as an argument to the next function in the array:Promise.reduce([ () => { reutrn Promise.resolve(['Felix', 'Garfield']) }, (cats) => { return Promise.resolve(['Rex', 'Lessie']) }, (dogs) => { return Promise.resolve(dogs) }, (turtles) => { return Promise.resolve(turtles) } ]) .then((results) => { // results = ['Rex', 'Lessie'] });
... And many more! Check out the full A-Z list of extensions!
Version History
1.0.X: First version with few patches, final patch 1.0.7
.
1.1.X: New Features:
fCombine
andfReduce
which behave likecombine
andreduce
, but make use of functions in the format(pars, callback(err, val))
instead of functions returning promises. This helps integrate async library functions that make use of callbacks instead of Promises.All functions now accept a second parameter which will be used as initial value for the sequence. See tests and documentation for some example.
1.2.X: New Features:
Extensions can now be concatenated with instance-specific functions: _aggregate
, _combine
, _fCombine
, _merge
, _reduce
, _fReduce
. These concatenation functions help switch composition context and structure on the go, but might end up confusing as for the value passed downstream. See tests for some working examples.
1.3.X: New Features:
Added
dev
warnings and errors for concatenation special cases:_aggregate
and_combine
will have non-object donwstreams assigned to an_init
variable in the aggregation object.Added
mux
anddeMux
functionality to mix several promises from an array or an object of inputs as if it were one. See tests for some cool example!
1.4.X: New Features:
Added
_aside
concatenation to execute side-operations alongside the downstream without affecting the downstream itself, even ignoring errors if desired.Added
or
,and
andxor
methods to handle logical composition of a sequence of Promises's results. For examble theor
operator doesn't even execute a successive Promise if any previous one succeeds, whileand
doesn't executre successive Promises of a failed one. Each logical operation "fails" if the downstream is undefined or if a given check function on the result is not met.Added
_or
,_and
and_xor
concat methods to chain logical block building with downstream data from other promises. These also work withmux
-ed Promises.
1.5.X: New Features:
Added some utility functions which can be useful to add expressivity to Promise chains and shorten some steps.
Added
_filter
and_shuffle
methods to muxed Promises. The_filter
method accept a filtering function and sets to undefined all the filtered out downstreams (the function should return true for passing downstreams only). Chaining a_clean()
after thedeMux
will finally remove the filtered-out undefined items from the downstream. The_shuffle
method simply shuffles the Promises in the mux pool (be it an Array or an Object) and keeps the new shuffled pool for chaining.
1.6.X: New Features:
Now base mix functions (aggregate, combine, merge, reduce) may accept some non-Promise values as well, this way you can build outputs more cleanly and you can skip writing chains to just return
Promise.resolve(val)
.Now combine and reduce may accept functions which do not return Promises, but "static values", so you don't have to return a
Promise.resolve(val)
in your function.
1.7.X: New Features:
Inverted
_when
parameters order: check comes first and function to execute if check is true comes second.Added
_ifElse
function that checks a condition, then executes an if-function if the check returns true, or an elseFunction if the check returns false.Added
_exists
function which is like_check
but only accepts the error which is thrown if the downstream is evaluated to false.
1.8.X: Flexible Mapping! New Features:
Introduced the concept of
Operation
to wrap any argunet of basic composition functions (aggregate
,combine
,fCombine
,merge
,reduce
andfReduce
). This way you can now put anything you like as items (or fields) of the composition map.As a result of point 1
aggregate
is now deprecated as its behaviour is now replicable with acombine
.Operation
s also work as_ifElse
and_when
"effects" (thecheck
function is still a plainFunction
). Same goes for the_aside
function which is now a genericOperation
.Converstion of callback-style
Functions
intoPromises
withpromisify
is now atOperation
level, so each base function (aggregate
,combine
,fCombine
,merge
,reduce
andfReduce
) now has apromisify
optional flag (last optional parameter) which enables/disables thepromisify
conversion for all the given functions. If you wish topromisify
only a specific step of your composition map, then you can create anOperation
passing your callback function and thepromisify
flagtrue
to its constructor. This change makesfReduce
andfCombine
obsolete, but they're kept as more direct method to handle promisified functions.