hstarorg/HstarDoc

实现简单的并发请求控制

hstarorg opened this issue · 5 comments

题目:请实现如下的函数,可以批量请求数据,所有的URL地址在 urls 参数中,同时可以通过 max 参数控制请求的并发数,当所有的请求结束之后,需要执行 callback 回调函数。发请求的函数可以直接使用 fetch 即可。

function sendRequest(urls: string[], max: number, callback: () => void){
}

First version:

function sendRequest(urls, max, callback) {
  const len = urls.length;
  let currentIdx = Math.min(len, max);
  let counter = 0;

  function _done() {
    counter += 1;
    // All done.
    if (counter === len) {
      return callback();
    }
    // Append to queue.
    _fetch(urls[currentIdx++]);
  }

  function _fetch(url) {
    fetch(url).finally(() => {
      _done();
    });
  }

  for (var i = 0; i < currentIdx; i++) {
    _fetch(urls[i]);
  }
}

Usage:

var urls = new Array(24).fill(true).map((x, i) => `https://github.com/hstarorg/HstarDoc/issues/${i + 1}`);

sendRequest(urls, 5, function() {
  console.log('done');
});

Second version:

function sendRequest(urls, max, callback) {
  const len = urls.length;
  let currentIdx = Math.min(len, max);
  let counter = 0;

  function _done() {
    counter += 1;
    // All done.
    if (counter === len) {
      return callback();
    }
    // Append to queue.
    if (currentIdx < len) {
      _fetch(urls[currentIdx++]);
    }
  }

  function _fetch(url) {
    fetch(url).finally(() => {
      _done();
    });
  }

  for (var i = 0; i < currentIdx; i++) {
    _fetch(urls[i]);
  }
}

Another version:

function sendRequest(urls, max, callback) {
  const len = urls.length;
  let idx = 0;
  let counter = 0;

  function _request() {
    // 有请求,有通道
    while (idx < len && max > 0) {
      max--; // 占用通道
      fetch(urls[idx++]).finally(() => {
        max++; // 释放通道
        counter++;
        if (counter === len) {
          return callback();
        } else {
          _request();
        }
      });
    }
  }
  _request();
}

幻神,请问这道题能不能用RxJS解啊,思路又是怎样的。