递归实现的异步并发控制

回到文章
<div class="manager">
  <p>并发数量:<select id="limit"></select></p>
  <button id="start">开始</button>
</div>
<div id="container"></div>
.manager {
  width: 300px;
  display: flex;
  justify-content: space-between;
}
#limit {
  width: 60px;
  font-size: 16px;
}
#start {
  font-size: 16px;
  width: 100px;
}
#container div {
  transition: width linear;
  min-height: 14px;
  background-color: #009688;
  color: #fff;
  margin-bottom: 4px;
  text-indent: 4px;
  width: 0;
}
/**
 * 递归方式实现异步并发控制
 * @param arr 所有的数据集合,如请求的url等
 * @param limit 限制并发的个数
 * @param iteratorFn 对每个数据的处理
 */
function promiseLimit(arr, limit, iteratorFn) {
  const { length } = arr;
  const result = [];
  let i = 0;
  let finishedNum = 0;

  return new Promise((resolve) => {
    const request = async (index) => {
      kk.show(arr[index], index);
      const p = Promise.resolve().then(() => iteratorFn(arr[index]));
      const res = await p;

      result[index] = res;
      finishedNum++;
      if (finishedNum === length) {
        resolve(result);
      }
      if (i < length) {
        request(i);
        i++;
      }
    };

    for (; i < limit; i++) {
      request(i);
    }
  });
};