/**
 * @param {Function[]} functions
 * @param {number} n
 * @return {Function}
 */
var promisePool = async function(functions, n) {
    return new Promise((resolve, reject) => {
        let in_progress = 0;
        let next = 0;

        function progress() {
            if (next >= functions.length) {
                if (in_progress == 0) {
                    resolve();
                }

                return;
            }

            while (in_progress < n && next < functions.length) {
                in_progress++;

                functions[next++]().then(() => {
                    in_progress--;
                    progress();
                });
            }
        }

        progress();
    });
};

/**
 * const sleep = (t) => new Promise(res => setTimeout(res, t));
 * promisePool([() => sleep(500), () => sleep(400)], 1)
 *   .then(console.log) // After 900ms
 */