function concurrentProcess(limit, list) {
        var total = list.length;
        return limit >= total ?
            Promise.all(list.map(function (promise) { return promise(); })) :
            new Promise(function (resolve) {
                next({ concurrent: 0, queued: 0, queue: [] });
                function next(meta, previous) {
                    // previous parameter is used only for logging
                    var queue = meta.queue, queued = meta.queued, concurrent = meta.concurrent;
                    if (queued == total)
                        return concurrent == 0 ? complete(queue) : null;
                    queue.push(list[queued]());
                    queue[queue.length - 1].then(function () {
                        concurrency(false, meta);
                        next(meta, queued);
                    });
                    console.log(previous === undefined ?
                        "Queued >>>  " + queued.toString().padStart(3, " ") :
                        "Queued >>>  " + queued.toString().padStart(3, " ") + "  <<< " + previous.toString().padStart(3, " "));
                    concurrency(true, meta) < limit && next(meta);
                }
                function concurrency(flag, meta) {
                    flag ? (meta.queued++, meta.concurrent++) : (meta.concurrent--);
                    return meta.concurrent;
                }
                function complete(queue) {
                    resolve(Promise.all(queue));
                }
            });
    }
/**
     * Processes a list of promises in queue with limited concurency, helps to avoid overloading clients during bulk processing
     * @param {number} limit number of promises to process concurrently
     * @param {Array<Function>} list list of functions that returns promises to be procesed
     * @returns {Promise<Array>} promise
     */
Processes a list of promises in queue with limited concurency, helps to avoid overloading clients during bulk processing
@param {number} limit number of promises to process concurrently
@param {Array} list list of functions that returns promises to be procesed
@returns {Promise} promise
Processes a list of promises in queue with limited concurency helps to avoid overloading clients during bulk processing @param { number } limit number of promises to process concurrently @param { Array } list list of functions that returns promises to be procesed @returns { Promise } promise
function concurrentProcess(limit, list) {
        var total = list.length;
        return limit >= total ?
            Promise.all(list.map(function (promise) { return promise(); })) :
            new Promise(function (resolve) {
                next({ concurrent: 0, queued: 0, queue: [] });
                function next(meta, previous) {
                    var queue = meta.queue, queued = meta.queued, concurrent = meta.concurrent;
                    if (queued == total)
                        return concurrent == 0 ? complete(queue) : null;
                    queue.push(list[queued]());
                    queue[queue.length - 1].then(function () {
                        concurrency(false, meta);
                        next(meta, queued);
                    });
                    console.log(previous === undefined ?
                        "Queued >>>  " + queued.toString().padStart(3, " ") :
                        "Queued >>>  " + queued.toString().padStart(3, " ") + "  <<< " + previous.toString().padStart(3, " "));
                    concurrency(true, meta) < limit && next(meta);
                }
                function concurrency(flag, meta) {
                    flag ? (meta.queued++, meta.concurrent++) : (meta.concurrent--);
                    return meta.concurrent;
                }
                function complete(queue) {
                    resolve(Promise.all(queue));
                }
            });
    }
function concurrentProcess ( limit , list ) { var total = list . length ; return limit >= total ? Promise . all ( list . map ( function ( promise ) { return promise ( ) ; } ) ) : new Promise ( function ( resolve ) { next ( { concurrent : 0 , queued : 0 , queue : [ ] } ) ; function next ( meta , previous ) { var queue = meta . queue , queued = meta . queued , concurrent = meta . concurrent ; if ( queued == total ) return concurrent == 0 ? complete ( queue ) : null ; queue . push ( list [ queued ] ( ) ) ; queue [ queue . length - 1 ] . then ( function ( ) { concurrency ( false , meta ) ; next ( meta , queued ) ; } ) ; console . log ( previous === undefined ? "Queued >>>  " + queued . toString ( ) . padStart ( 3 , " " ) : "Queued >>>  " + queued . toString ( ) . padStart ( 3 , " " ) + "  <<< " + previous . toString ( ) . padStart ( 3 , " " ) ) ; concurrency ( true , meta ) < limit && next ( meta ) ; } function concurrency ( flag , meta ) { flag ? ( meta . queued ++ , meta . concurrent ++ ) : ( meta . concurrent -- ) ; return meta . concurrent ; } function complete ( queue ) { resolve ( Promise . all ( queue ) ) ; } } ) ; }
Processes a list of promises in queue with limited concurency, helps to avoid overloading clients during bulk processing
 @param {number} limit number of promises to process concurrently
 @param {Array<Function>} list list of functions that returns promises to be procesed
 @returns {Promise<Array>} promise
Processes a list of promises in queue with limited concurency helps to avoid overloading clients during bulk processing @param { number } limit number of promises to process concurrently @param { Array<Function > } list list of functions that returns promises to be procesed @returns { Promise<Array > } promise
// previous parameter is used only for logging