AJAX调用for循环不会返回值来纠正数组位置

时间:2010-03-08 21:53:23

标签: javascript jquery ajax

我需要使用AJAX获取一系列页面并将它们放入一个数组中,其中数组中给定的位置等于for循环的i(它是博客页面的类似缓存的函数,for循环的范围完全可变)。我正在做类似以下的事情:

var bongo = new Array();

for (i = 0; i < 10; i++) {

    jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString, success: function(request) { bongo[i] = request } })

}

问题是,除非我将async: false添加到.ajax选项(这会使它... SJAX?),这会导致请求基本上暂停浏览器,违背我正在尝试的要做的是,成功回调中的i总是最终为11,而我当然希望它将返回的数据倒入数组的每个插槽中,从0到10。

我尝试用这个替换这行:

bongo[i] = jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString }).responseText

但这没有任何区别。

2 个答案:

答案 0 :(得分:39)

你需要一个闭包:

var bongo = [];
for (i = 0; i < 10; i++)
{

  (function(i)
    {
      jQuery.ajax(
        {
          type: "GET",
          url: "http://localhost",
          data: queryString,
          success: function(request) { bongo[i] = request } 
        });  
    })(i);
}

循环是内联函数残留人的第一名。直到稍后才会调用bongo[i] = result。那时i的值是不同的(很可能是11)。如果要“陷阱”或“捕获”i当前值,则需要创建新范围。在javascript中执行此操作的唯一方法是使用其他函数。

答案 1 :(得分:4)

尝试:

var bongo = [];
for (i=0; i<10; i++) {
  $.get("http://localhost", function(result) {
    bongo.push(result);
  }
}

这样,每个结果都会被推送到数组上,从而解决了数组索引正确的需要。但是不保证订单。如果这是一项要求,您将需要另一种方法。

有多种方法可以解决这个问题。这是一个:为回调创建对象以保存状态。这是一个例子:

function Callback(array, index, result) {
  this.array = array;
  this.index = index;
  this.result = result;
  var obj = this;
  this.func = function() {
    obj.array[obj.index] = obj.result;
  };
}

$(function() {
  var arr = [];
  for (var i=0; i<4; i++) {
    var obj = new Callback(arr, i, "result" + i);
    setTimeout(obj.func, (5-i) * 100);
  }
  setTimeout(function() {
    console.log(arr);
  }, 500);
});

所以在你的情况下:

function Callback(array, index) {
  this.array = array;
  this.index = index;
  var obj = this;
  this.callback = function(result) {
    obj.array[obj.index] = result;
  };
}

var bongo = [];
for (i=0; i<10; i++) {
  var ob = new Callback(bongo, i);
  $.get("http://localhost", ob.callback);
}

基本上上面将所有数据保存到对象中,因此每个回调都可以访问正确的信息。

另外,请记住,大多数浏览器限制并发AJAX请求的数量,通常为每个主机2个。