JSFiddle - React, Tailwind, and code Playground

JavaScript

async function* makeALotOfWork() {
	let id = 0;
  while (true) {
  	yield ({ id: id++, delay: Math.floor(Math.random() * 1000) + 10 });
  }
}

function makeWork(t) {
	t.promise = new Promise(resolve => setTimeout(() => resolve(t), t.delay));
  return t;
}

async function* map(tasks, n) {
  // Start n work
  const parallel = new Set();
  for (let i = 0; !tasks.done && i < n; ++i) {
  	parallel.add(makeWork((await tasks.next()).value));
  }
  // Process the work yielding the first one done in the set of n work
	while (parallel.length != 0 && !tasks.done) {
  	const task = await Promise.race([...parallel].map(t => t.promise));
    parallel.delete(task);
    yield task;
    // Add 1 more work
    parallel.add(makeWork((await tasks.next()).value));
  }
  console.log('map done');
}

(async () => {
  let workDone = 0;
  for await (const t of map(map(makeALotOfWork(), 5), 5)) {
  	console.log(t.id, t.delay);
    workDone++;
    if (workDone > 20) {
      break;
    }
  }
})();