mapFunAsync

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

    Usage

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

    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/async/map-function' );
    
    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 );