promise-utils

promise-utils is a Javascript library that provides utilities for working with promises. promise-utils can be used as a monad library for promises or each function can be used standalone.

This library uses promise-extended internally but can be used with any promises A+ compliant library such as Q

promise-utils can be used standalone or incorporated into extended

var pUtils = require ( "promise-utils" );

Or

var myextended = require ( "extended" ) . register ( require ( "promise-extended" ));

Installation

npm install promise-utils

Or download the source (minified)

Usage

Arrays

promise-utils can be used with promises or normal arrays by using the async method.

NOTE The examples below uses a resolve method which represents turning an array into a promise resolved with the given array. This is used for brevity where you would typically be working with promises returned from an asynchronous method such as a database call.

var arr = [ 1 , 2 , 3 ]; var promiseArr = resolve ( arr ); pUtils ( arr ). async (). forEach ( function ( item ){ console . log ( item ); }). then ( function (){ console . log ( "Done Looping" ); }); //OR pUtils ( promiseArr ). forEach ( function ( item ){ console . log ( item ); }). then ( function (){ console . log ( "Done Looping" ); });

Chaining

When using promise-utils as a monad with a promise you may chain methods together.

var arr = resolve ([ 1 , 2 , 3 , 4 , 5 ]); pUtils ( arr ) . map ( function ( num , i ) { return num * ( i + 1 ); }) . filter ( function ( num ) { return num % 2 ; }) . avg () . then ( function ( res ){ //11.666666666666666 });

forEach

Similar to Array#forEach except that it resolves with the original array for chaining.

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). forEach ( function ( item ){ console . log ( item ); }). then ( function (){ console . log ( "Done Looping" ); }); pUtils . forEach ( resolve ([ 1 , 2 , 3 ]), function ( item ){ console . log ( item ); }). then ( function (){ console . log ( "Done Looping" ); });

You may also return a promise from the iterator function, which will prevent the returned promise from resolving until all the returned promises are done.

pUtils ( resolve ([ 1 , 2 , 3 ])). forEach ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item ); }, 200 ); return ret . promise (); }). then ( function (){ //all promises from iterator function are resolved. console . log ( "Done Looping" ); });

You may also specify a limit which will specify the number of items to be looped at a time, if limit is not specified then all items will be iterated regardless of whether or not the previous item in the array is done.

pUtils ( resolve ([ 1 , 2 , 3 ])). forEach ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item ); }, 200 ); return ret . promise (); }, 1 ). then ( function (){ console . log ( "Done Looping" ); });

In the above example only one item will be iterated one at a time.

map

Async version of Array#map .

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). map ( function ( item ){ return item * 2 ; }). then ( function ( result ){ console . log ( result ); //[2, 4, 6]; }); pUtils . map ( resolve ([ 1 , 2 , 3 ]), function ( item ){ return item * 2 ; }). then ( function ( result ){ console . log ( result ); //[2, 4, 6]; });

You may also return a promise from the iterator function, which will prevent the returned promise from resolving until all the returned promises are done.

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). map ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item * 2 ); }, 200 ); return ret . promise (); }). then ( function ( result ){ console . log ( result ); //[2, 4, 6]; });

You may also specify a limit which will specify the number of items to be looped at a time, if limit is not specified then all items will be iterated regardless of whether or not the previous item in the array is done.

pUtils ( resolve ([ 1 , 2 , 3 ])). map ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item * 2 ); }, 200 ); return ret . promise (); }, 1 ). then ( function (){ console . log ( result ); //[2, 4, 6]; });

In the above example only one item will be iterated at a time.

filter

Async version of Array#filter .

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). filter ( function ( item ){ return item % 2 ; }). then ( function ( result ){ console . log ( result ); //[1, 3]; }); pUtils . filter ( resolve ([ 1 , 2 , 3 ]), function ( item ){ return item % 2 ; }). then ( function ( result ){ console . log ( result ); //[1, 3]; });

You may also return a promise from the iterator function, which will prevent the returned promise from resolving until all the returned promises are done.

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). filter ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item % 2 ); }, 200 ); return ret . promise (); }). then ( function ( result ){ console . log ( result ); //[1, 3]; });

You may also specify a limit which will specify the number of items to be looped at a time, if limit is not specified then all items will be iterated regardless of whether or not the previous item in the array is done.

pUtils ( resolve ([ 1 , 2 , 3 ])). filter ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item % 2 ); }, 200 ); return ret . promise (); }, 1 ). then ( function (){ console . log ( result ); //[1, 3]; });

In the above example only one item will be iterated at a time.

every

Async version of Array#every .

pUtils ( resolve ([ 1 , 2 , 3 ])). every ( function ( item ){ return isNumber ( item ); }). then ( function ( result ){ console . log ( result ); //true; }); pUtils . every ( resolve ([ 1 , 2 , 3 ]), function ( item ){ return isNumber ( item ); }). then ( function ( result ){ console . log ( result ); //true; });

You may also return a promise from the iterator function, which will prevent the returned promise from resolving until all the returned promises are done.

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). every ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( isNumber ( item )); }, 200 ); return ret . promise (); }). then ( function ( result ){ console . log ( result ); //[true]; });

You may also specify a limit which will specify the number of items to be looped at a time, if limit is not specified then all items will be iterated regardless of whether or not the previous item in the array is done.

pUtils ( resolve ([ 1 , 2 , 3 ])). every ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( isNumber ( item )); }, 200 ); return ret . promise (); }, 1 ). then ( function (){ console . log ( result ); //true; });

In the above example only one item will be iterated at a time.

some

Async version of Array#every .

pUtils ( resolve ([ 1 , 2 , 3 ])). some ( function ( item ){ return item === 1 ; }). then ( function ( result ){ console . log ( result ); //true; }); pUtils . some ( resolve ([ 1 , 2 , 3 ]), function ( item ){ return item === 1 ; }). then ( function ( result ){ console . log ( result ); //true; });

You may also return a promise from the iterator function, which will prevent the returned promise from resolving until all the returned promises are done.

//as a monad pUtils ( resolve ([ 1 , 2 , 3 ])). some ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item === 1 ); }, 200 ); return ret . promise (); }). then ( function ( result ){ console . log ( result ); //[true]; });

You may also specify a limit which will specify the number of items to be looped at a time, if limit is not specified then all items will be iterated regardless of whether or not the previous item in the array is done.

pUtils ( resolve ([ 1 , 2 , 3 ])). some ( function ( item ){ var ret = new Promise (); setTimeout ( function (){ ret . callback ( item === 1 ); }, 200 ); return ret . promise (); }, 1 ). then ( function (){ console . log ( result ); //true; });

In the above example only one item will be iterated at a time.

sum

Sums the values of an array

pUtils . sum ( resolve ([ 1 , 2 , 3 ])). then ( function ( sum ){ //6 }); pUtils ( resolve ([ 1 , 2 , 3 ])). sum (). then ( function ( sum ){ //6 });

avg

Finds the average of an array of numbers.

pUtils . avg ( resolve ([ 1 , 2 , 3 ])). then ( function ( avg ){ //2 }); pUtils ( resolve ([ 1 , 2 , 3 ])). avg (). then ( function ( avg ){ //2 });

sort

Sorts an array based on a property, by natural ordering, or by a custom comparator.

Note this does not change the original array.

pUtils . sort ( resolve ([{ a : 1 },{ a : 2 },{ a : - 2 }]), "a" ). then ( function ( sorted ){ //[{a: -2},{a: 1},{a: 2}]; }) pUtils ( resolve ([{ a : 1 },{ a : 2 },{ a : - 2 }])). sort ( "a" ). then ( function ( sorted ){ //[{a: -2},{a: 1},{a: 2}]; })

min

Finds the minimum value in an array based on a property, by natural ordering, or by a custom comparator.

pUtils . min ( resolve ([ 3 , - 3 , - 2 , - 1 , 1 , 2 ])). then ( function ( min ){ //-3 }); pUtils . min ( resolve ([{ a : 1 },{ a : 2 },{ a : - 2 }]), "a" ). then ( function ( min ){ //{a : -2} }); pUtils ( resolve ([ 3 , - 3 , - 2 , - 1 , 1 , 2 ])). min (). then ( function ( min ){ //-3 }); pUtils ( resolve ([{ a : 1 },{ a : 2 },{ a : - 2 }])). min ( "a" ). then ( function ( min ){ //{a : -2} });

max

Finds the maximum value in an array based on a property, by natural ordering, or by a custom comparator.

pUtils . max ( resolve ([ 3 , - 3 , - 2 , - 1 , 1 , 2 ])). then ( function ( max ){ //2 }); pUtils . max ( resolve ([{ a : 1 },{ a : 2 },{ a : - 2 }]), "a" ). then ( function ( max ){ //{a : 2} }); pUtils ( resolve ([ 3 , - 3 , - 2 , - 1 , 1 , 2 ])). max (). then ( function ( max ){ //2 }); pUtils ( resolve ([{ a : 1 },{ a : 2 },{ a : - 2 }])). max ( "a" ). then ( function ( max ){ //{a : 2} });

difference

Finds the difference between two arrays.

pUtils . difference ( resolve ([ 1 , 2 , 3 ]), [ 2 ]). then ( function ( diff ){ //[1, 3] }); pUtils . difference ( resolve ([ true , false ]), resolve ([ false ])). then ( function ( diff ){ //[true] }); pUtils . difference ( resolve ([ "a" , "b" , 3 ]), resolve ([ 3 ])). then ( function ( diff ){ //["a", "b"] }); pUtils . difference ( resolve ([{ a : 1 }, { a : 2 }, { a : 3 }]), resolve ([{ a : 2 }, { a : 3 }])). then ( function ( diff ){ //[{a: 1}] }); pUtils ( resolve ([ true , false ])). difference ([ false ]). then ( function ( diff ){ // [true] }); pUtils ( resolve ([ 1 , 2 , 3 ])). difference ( resolve ([ 2 ])). then ( function ( diff ){ // [1, 3] }); pUtils ( resolve ([ 1 , 2 , 3 ])). difference ([ 2 ], resolve ([ 3 ])). then ( function ( diff ){ //[1] }); pUtils ( resolve ([ "a" , "b" , 3 ])). difference ([ 3 ]). then ( function ( diff ){ //["a", "b"] }); pUtils ( resolve ([{ a : 1 }, { a : 2 }, { a : 3 }])). difference ( resolve ([{ a : 2 }, { a : 3 }])). then ( function ( diff ){ // [{a: 1}] });

unique

Removed duplicate values from an array

pUtils . unique ( resolve ([ 1 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 ])). then ( function ( unique ){ //[1, 2, 3, 4] }) : pUtils ( resolve ([ 1 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 ])). unique (). then ( function ( unique ){ //[1, 2, 3, 4] }); pUtils ( resolve ([ "a" , "b" , "b" ])). unique (). then ( function ( unique ){ //["a", "b"] }); pUtils . unique ( resolve ([ "a" , "b" , "b" ])). then ( function ( unique ){ //["a", "b"] });

rotate

Rotates an array by the number of places for 1 position by default.

var arr = pUtils ( resolve ([ "a" , "b" , "c" , "d" ])) arr . rotate (); //resolves with ["b", "c", "d", "a"] arr . rotate ( 2 ); //resolves with ["c", "d", "a", "b"] arr . rotate ( 3 ); //resolves with ["d", "a", "b", "c"] arr . rotate ( 4 ); //resolves with ["a", "b", "c", "d"] arr . rotate ( - 1 ); //resolves with ["d", "a", "b", "c"] arr . rotate ( - 2 ); //resolves with ["c", "d", "a", "b"] arr . rotate ( - 3 ); //resolves with ["b", "c", "d", "a"] arr . rotate ( - 4 ); //resolves with ["a", "b", "c", "d"] arr = resolve ([ "a" , "b" , "c" , "d" ]); pUtils . rotate ( arr ); //resolves with ["b", "c", "d", "a"] pUtils . rotate ( arr , 2 ); //resolves with ["c", "d", "a", "b"] pUtils . rotate ( arr , 3 ); //resolves with ["d", "a", "b", "c"] pUtils . rotate ( arr , 4 ); //resolves with ["a", "b", "c", "d"] pUtils . rotate ( arr , - 1 ) //resolves with ["d", "a", "b", "c"] pUtils . rotate ( arr , - 2 ); //resolves with ["c", "d", "a", "b"] pUtils . rotate ( arr , - 3 ); //resolves with ["b", "c", "d", "a"] pUtils . rotate ( arr , - 4 ); //resolves with ["a", "b", "c", "d"]

permutations

Finds all permutations of an array.

pUtils ( resolve ([ 1 , 2 , 3 ])). permutations (); //resolves with [ // [ 1, 2, 3 ], // [ 1, 3, 2 ], // [ 2, 3, 1 ], // [ 2, 1, 3 ], // [ 3, 1, 2 ], // [ 3, 2, 1 ] //] pUtils ( resolve ([ 1 , 2 , 3 ])). permutations ( 2 ); // resolves with [ // [ 1, 2], // [ 1, 3], // [ 2, 3], // [ 2, 1], // [ 3, 1], // [ 3, 2] //] pUtils . permutations ( resolve ([ 1 , 2 , 3 ])); // resolves with [ // [ 1, 2, 3 ], // [ 1, 3, 2 ], // [ 2, 3, 1 ], // [ 2, 1, 3 ], // [ 3, 1, 2 ], // [ 3, 2, 1 ] //] pUtils . permutations ( resolve ([ 1 , 2 , 3 ]), 2 ); //resolves with [ // [ 1, 2], // [ 1, 3], // [ 2, 3], // [ 2, 1], // [ 3, 1], // [ 3, 2] //]

zip

Zips the values of multiple arrays into a single pUtils.

pUtils ( resolve ([ 1 ])). zip ( resolve ([ 2 ]), resolve ([ 3 ])); //resolves with [ // [ 1, 2, 3 ] //]; pUtils ( resolve ([ 1 , 2 ])). zip ( resolve ([ 2 ]), [ 3 ]); //resolves with [ // [ 1, 2, 3 ], // [2, null, null] //] pUtils ( resolve ([ 1 , 2 , 3 ])). zip ([ 4 , 5 , 6 ], b ); //resolves with [ // [1, 4, 7], // [2, 5, 8], // [3, 6, 9] //] pUtils ( resolve ([ 1 , 2 ])). zip ([ 4 , 5 , 6 ], resolve ([ 7 , 8 , 9 ])); //resolves with [ // [1, 4, 7], // [2, 5, 8] //] pUtils ( resolve ([ 4 , 5 , 6 ])). zip ([ 1 , 2 ], [ 8 ]); //resolves with [ // [4, 1, 8], // [5, 2, null], // [6, null, null] //] pUtils . zip ( resolve ([ 1 ]), [ 2 ], [ 3 ]); //resolves with [ // [ 1, 2, 3 ] //] pUtils . zip ( resolve ([ 1 , 2 ]), resolve ([ 2 ]), [ 3 ]); //resolves with [ // [ 1, 2, 3 ], // [2, null, null] //] pUtils . zip ( resolve ([ 1 , 2 , 3 ]), [ 4 , 5 , 6 ], resolve ([ 7 , 8 , 9 ])); //resolves with [ // [1, 4, 7], // [2, 5, 8], // [3, 6, 9] //] pUtils . zip ( resolve ([ 1 , 2 ]), [ 4 , 5 , 6 ], [ 7 , 8 , 9 ]); //resolves with [ // [1, 4, 7], // [2, 5, 8] //] pUtils . zip ([ 4 , 5 , 6 ], [ 1 , 2 ], resolve ([ 8 ])); //resolves with [ // [4, 1, 8], // [5, 2, null], // [6, null, null] //]

transpose

Transpose a multi dimensional array.

pUtils ( resolve ([[ 1 , 2 , 3 ],[ 4 , 5 , 6 ]])). transpose (); //resolves with [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] pUtils ([[ 1 , 2 ],[ 3 , 4 ],[ 5 , 6 ]]). async (). transpose (); //resolves with [ [ 1, 3, 5 ], [ 2, 4, 6 ] ] pUtils ( resolve ([[ 1 ],[ 3 , 4 ],[ 5 , 6 ]])). transpose (); //resolves with [ [1] ] pUtils . transpose ( resolve ([[ 1 , 2 , 3 ],[ 4 , 5 , 6 ]])); //resolves with [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] pUtils . transpose ( resolve ([[ 1 , 2 ],[ 3 , 4 ],[ 5 , 6 ]])); //resolves with [ [ 1, 3, 5 ], [ 2, 4, 6 ] ] pUtils . transpose ( resolve ([[ 1 ],[ 3 , 4 ],[ 5 , 6 ]])); //resolves with [ [1] ]

valuesAt

Gathers values at the specified indexes.

var arr = pUtils ( resolve ([ "a" , "b" , "c" , "d" ])); arr . valuesAt ( 1 , 2 , 3 ); //resolves with ["b", "c", "d"] arr . valuesAt ( 1 , 2 , 3 , 4 ); //resolves with ["b", "c", "d", null] arr . valuesAt ( 0 , 3 ); //resolves with ["a", "d"] arr = resolve ([ "a" , "b" , "c" , "d" ]); pUtils . valuesAt ( arr , 1 , 2 , 3 ); //resolves with ["b", "c", "d"] pUtils . valuesAt ( arr , 1 , 2 , 3 , 4 ); //resolves with ["b", "c", "d", null] pUtils . valuesAt ( arr , 0 , 3 ); //resolves with ["a", "d"]

union

Finds the union of two arrays.

pUtils ( resolve ([ "a" , "b" , "c" ])). union ([ "b" , "c" , "d" ]); //resolves with ["a", "b", "c", "d"]); pUtils ([ "a" ]). async (). union ([ "b" ], [ "c" ], [ "d" ], resolve ([ "c" ])); //resolves with ["a", "b", "c", "d"]); pUtils . union ( resolve ([ "a" , "b" , "c" ]), [ "b" , "c" , "d" ]); //resolves with ["a", "b", "c", "d"]); pUtils . union ( resolve ([ "a" ]), [ "b" ], resolve ([ "c" ]), [ "d" ], [ "c" ]); //resolves with ["a", "b", "c", "d"]);

intersect

Finds the intersection of arrays.

pUtils ( resolve ([ 1 , 2 ])). intersect ([ 2 , 3 ], [ 2 , 3 , 5 ]); //resolves with [2]; pUtils ( resolve ([ 1 , 2 , 3 ])). intersect ([ 2 , 3 , 4 , 5 ], [ 2 , 3 , 5 ]); //resolves with [2, 3]; pUtils ( resolve ([ 1 , 2 , 3 , 4 ])). intersect ([ 2 , 3 , 4 , 5 ], [ 2 , 3 , 4 , 5 ]); //resolves with [2, 3, 4]; pUtils ( resolve ([ 1 , 2 , 3 , 4 , 5 ])). intersect ([ 1 , 2 , 3 , 4 , 5 ], [ 1 , 2 , 3 ]); //resolves with [1, 2, 3]; pUtils ( resolve ([[ 1 , 2 , 3 , 4 , 5 ],[ 1 , 2 , 3 , 4 , 5 ],[ 1 , 2 , 3 ]])). intersect (); //resolves with [1, 2, 3]; pUtils . intersect ( resolve ([ 1 , 2 ]), [ 2 , 3 ], [ 2 , 3 , 5 ]); //resolves with [2] pUtils . intersect ( resolve ([ 1 , 2 , 3 ]), [ 2 , 3 , 4 , 5 ], [ 2 , 3 , 5 ]); //resolves with [2, 3] pUtils . intersect ( resolve ([ 1 , 2 , 3 , 4 ]), [ 2 , 3 , 4 , 5 ], resolve ([ 2 , 3 , 4 , 5 ])); //resolves with [2, 3, 4] pUtils . intersect ( resolve ([ 1 , 2 , 3 , 4 , 5 ]), [ 1 , 2 , 3 , 4 , 5 ], [ 1 , 2 , 3 ]); //resolves with [1, 2, 3]); pUtils . intersect ( resolve ([[ 1 , 2 , 3 , 4 , 5 ],[ 1 , 2 , 3 , 4 , 5 ], [ 1 , 2 , 3 ]])); //resolves with [1, 2, 3]);

powerSet

Finds the powerset of a given array.

pUtils ( resolve ([ 1 , 2 , 3 ])). powerSet (); pUtils . powerSet ( resolve ([ 1 , 2 , 3 ])); //Both resolve with //[ // [], // [ 1 ], // [ 2 ], // [ 1, 2 ], // [ 3 ], // [ 1, 3 ], // [ 2, 3 ], // [ 1, 2, 3 ] //]

cartesian

Finds the cartesian product of arrays.

pUtils ( resolve ([ 1 , 2 ])). cartesian ( resolve ([ 2 , 3 ])); pUtils . cartesian ( resolve ([ 1 , 2 ]), [ 2 , 3 ]); //Both resolve with //[ // [1, 2], // [1, 3], // [2, 2], // [2, 3] //]

compact

Compacts the values of an array.

pUtils ( resolve ([ 1 , null , null , x , 2 ])). compact (); //Resolves with [1, 2] pUtils ([ 1 , 2 ]). async (). compact (); //Resolves with [1, 2] pUtils . compact ( resolve ([ 1 , null , null , x , 2 ])); //Resolves with [1, 2] pUtils . compact ( resolve ([ 1 , 2 ])); //Resolves with [1, 2]

multiply

Reproduces the values in an array the given number of times.

pUtils ( resolve ([ 1 , 2 ])). multiply ( 2 ); //Resolves with[1, 2, 1, 2, 1, 2] pUtils . multiply ( resolve ([ 1 , 2 , 3 ]), 2 ); //Resolves with [1, 2, 3, 1, 2, 3]

flatten

Flatten multiple arrays into a single array.

pUtils ( resolve ([ [ 1 ], [ 2 ], [ 3 ] ])). flatten (); //Resolves with [1, 2, 3] pUtils . flatten ( resolve ([ 1 , 2 ]), [ 2 , 3 ], resolve ([ 3 , 4 ])); //Resolves with [1, 2, 2, 3, 3, 4]

pluck

Pluck properties from values in an array.

NOTE Plucked properties may also be promises. pluck will return the resolved value of the promise

var arr = resolve ([ { name : { first : "Fred" , last : "Jones" }, age : 50 , roles : [ "a" , "b" , "c" ]}, { name : { first : resolve ( "Bob" ), last : "Yukon" }, age : resolve ( 40 ), roles : resolve ([ "b" , "c" ])}, { name : { first : "Alice" , last : "Palace" }, age : 35 , roles : [ "c" ]}, { name : { first : resolve ( "Johnny" ), last : "P." }, age : 56 , roles : resolve ([])} ]); pUtils . pluck ( arr , "name.first" ); //Resolves with ["Fred", "Bob", "Alice", "Johnny"] pUtils ( arr ). pluck ( "age" ); //Resolves with [50, 40, 35, 56]

invoke

Invokes the specified method on each value in an array.