function concurrentMap (input, concurrency, asyncFn) {
  if (!concurrency) {
    concurrency = os.cpus().length;
  }
  if (concurrency < 1) {
    throw new Error('Concurrency must be non-zero');
  }
  const queue = [];
  const ret = [];
  function next () {
    if (queue.length) {
      queue.shift()();
    }
  }
  for (let i = 0; i < input.length; i++) {
    const val = input[i];
    if (i < concurrency) {
      ret[i] = Promise.resolve(asyncFn(val));
    } else {
      let trigger;
      const promise = new Promise((resolve) => {
        trigger = resolve;
      });
      queue.push(trigger);

      ret[i] = promise.then(asyncFn.bind(null, val));
    }
    // Avoid premature UnhandledPromiseRejectionWarning
    ret[i].catch(() => null).finally(next);
  }
  return ret;
}
@param {Array<number,any>} input
@param {number} [concurrency=0]
@return {Array<number,Promise>}