XMLHttpRequest循环内存泄漏

时间:2013-12-15 23:07:53

标签: javascript jquery ajax xmlhttprequest

我正在尝试根据ajax网址上的信息检查许多项目。但是当我在浏览器中运行此功能时,内存使用量超过2 gig然后浏览器崩溃(Chrome,Firefox)。我究竟做错了什么? items变量非常大 - > 200 000并且还包含一些大字符串。

var items = [1,2,3,4,5,6,7,8,9,10,...,300000]
var activeItems = {}

function loopAjax(){
    for (i=0; i < items.length; i++) {
        var currItem = items[i];
        var request = new XMLHttpRequest();
        var found = 0

        request.open("GET", "/item=" + currItem);
        request.onreadystatechange = function() {
            if (request.readyState == 4 && request.status == 200) {
                var response = JSON.parse(request.responseText);
                var active = response[0].active;
                if (active) {
                    console.log("FOUND ACTIVE! " + currItem);
                    activeItems[found] = {"active": true, "item": currItem};
                    found++;
                }
            }
        }
        request.send();
    }
}

1 个答案:

答案 0 :(得分:2)

谢天谢地,浏览器停滞不前。如果它没有创建拒绝服务攻击!

需要重新审核此问题。最好创建一个状态机,其中包含一堆请求。这样你一次只能说5个并发请求。

function ItemChecker(sample_size, max_threads) {
  this.sample_size = sample_size;
  this.max_threads = max_threads;
  this.counter = 0;
  this.activeItems = [];
  this.isRunning = false;
  this.running_count = 0;
}

ItemChecker.prototype.start = function start() {
  this.isRunning = true;
  while (this.running_count < this.max_threads) {
    this.next();
  }
  return this;
};

ItemChecker.prototype.stop = fucntion stop() {
  this.isRunning = false;
  return this;
};

ItemChecker.prototype.next = function next() {
  var request, item_id, _this = this;

  function xhrFinished(req) {
    var response;
    if (req.readyState !== 4) {
      return;
    }

    _this.counter--;

    if (req.status === 200) {
      try {
        response = JSON.parse(request.responseText);
        if (response[0].active) {
          _this.activeItems.push({
            active: true,
            item: item_id;
          });
        }
      } catch(e) {
        console.error(e);
      }

      // When finished call a callback
      if (_this.onDone && _this.counter >= _this.sample_size) {
        _this.onDone(_this.activeItems);
      }
    }
    else {
      console.warn("Server returned " + req.status);
    }
  }

  if (!this.isRunning || this.counter >= this.sample_size) {
    return;
  }

  item_id = this.counter;
  this.counter++;

  request = new XMLHttpRequest();
  request.onreadystatechange = xhrFinished;
  request.open("GET", "item=" + item_id);
  request.send();
};

ItemChecker.prototype.whenDone = function whenDone(callback) {
  this.onDone = callback;
  return this;
};

这可能有用吗?没有真正尝试过。但你可以用它来称呼它:

var item_checker = new ItemChecker(300000, 5);
item_checker.whenDone(function(active) {
  // Do something with active
}).start();