mapFunAsync

Invoke a function n times and return an array of accumulated function return values.

Usage

var mapFunAsync = require( '@stdlib/utils/map-function-async' );

mapFunAsync( fcn, n, [options,] done )

Invokes a function n times and returns an array of accumulated function return values.

function fcn( i, next ) {
    var t = 300 - (i*50);
    setTimeout( onTimeout, t );
    function onTimeout() {
        console.log( i );
        next( null, i );
    }
}

function done( error, arr ) {
    if ( error ) {
        throw error;
    }
    console.log( arr );
}

mapFunAsync( fcn, 5, done );
/* =>
    4
    3
    2
    1
    0
    [ 0, 1, 2, 3, 4 ]
*/

For each iteration, the provided function is invoked with two arguments:

  • index: invocation index (starting from zero)
  • next: callback to be invoked upon function completion

The next callback accepts two arguments:

  • error: error argument
  • result: function result

The function accepts the following options:

  • limit: the maximum number of pending invocations at any one time. Default: infinity.
  • series: boolean indicating whether to sequentially invoke fcn. If true, the function sets options.limit=1. Default: false.
  • thisArg: the execution context for fcn.

By default, all invocations are performed concurrently, which means that the function does not guarantee completion order. To invoke a function such that only one invocation is pending at any one time, set the series option to true.

function fcn( i, next ) {
    var t = 300 - (i*50);
    setTimeout( onTimeout, t );
    function onTimeout() {
        console.log( i );
        next( null, i );
    }
}

function done( error, arr ) {
    if ( error ) {
        throw error;
    }
    console.log( arr );
}

var opts = {
    'series': true
};

mapFunAsync( fcn, 5, opts, done );
/* =>
    0
    1
    2
    3
    4
    [ 0, 1, 2, 3, 4 ]
*/

To limit the maximum number of pending function invocations, set the limit option.

var delays = [ 300, 250, 225, 150, 100 ];

function fcn( i, next ) {
    setTimeout( onTimeout, delays[ i ] );
    function onTimeout() {
        console.log( i );
        next( null, i );
    }
}

function done( error, arr ) {
    if ( error ) {
        throw error;
    }
    console.log( arr );
}

var opts = {
    'limit': 2
};

mapFunAsync( fcn, 5, opts, done );
/* =>
    1
    0
    3
    2
    4
    [ 0, 1, 2, 3, 4 ]
*/

To set the execution context of fcn, set the thisArg option.

function fcn( i, next ) {
    this.count += 1;
    setTimeout( onTimeout, 0 );
    function onTimeout() {
        next( null, i );
    }
}

function done( error, arr ) {
    if ( error ) {
        throw error;
    }
    console.log( arr );
    // => [ 0, 1, 2, 3, 4 ]
}

var ctx = {
    'count': 0
};
var opts = {
    'thisArg': ctx
};

mapFunAsync( fcn, 5, opts, done );

mapFunAsync.factory( [options,] fcn )

Returns a function which invokes a function n times and returns an array of accumulated function return values.

function fcn( i, next ) {
    var t = 300 - (i*50);
    setTimeout( onTimeout, t );
    function onTimeout() {
        console.log( i );
        next( null, i );
    }
}

function done( error, arr ) {
    if ( error ) {
        throw error;
    }
    console.log( arr );
}

var opts = {
    'series': true
};

var f = mapFunAsync.factory( opts, fcn );

f( 5, done );
/* =>
    0
    1
    2
    3
    4
    [ 0, 1, 2, 3, 4 ]
*/

f( 2, done );
/* =>
    0
    1
    [ 0, 1 ]
*/

The function accepts the same options as mapFunAsync().

Notes

  • If a provided function calls the next callback with a truthy error argument, the function suspends execution and immediately calls the done callback for subsequent error handling.
  • Neither mapFunAsync nor the function returned by the factory method guarantee asynchronous execution. To guarantee asynchrony, wrap the done callback in a function which either executes at the end of the current stack (e.g., nextTick) or during a subsequent turn of the event loop (e.g., setImmediate, setTimeout).

Examples

var randu = require( '@stdlib/random/base/randu' );
var mapFunAsync = require( '@stdlib/utils/map-function-async' );

function rand( i, next ) {
    var t = randu() * i;
    setTimeout( onTimeout, t );
    function onTimeout() {
        next( null, t );
    }
}

function done( error, out ) {
    if ( error ) {
        throw error;
    }
    console.log( out );
}

mapFunAsync( rand, 10, done );