异步AJAX调用让我的迭代器失败了

时间:2011-11-23 16:23:34

标签: javascript ajax asynchronous

我使用以下AJAX请求来检索许多页面,这些页面的标题名为pages。每个响应进入一个单独的div,我想给每个div一个id与页面标题相同。

当然,当我的请求回来时,[i]已达到pages.length,我所有的div名称都是undefined

for ( i = 0; i < pages.length; i++ ) {
  $.ajax({
    //async:false makes it work but it slows things down too much
    url: 'ajax_' + pages[i],
    success: function(data) {
      $('<div id="' + pages[i] + '">' + data + '</div>').appendTo('div.content');
      }
  });
 }

如何在请求和响应变量之间实现良好的锁步?

谢谢!

NB 我宁愿保持异步(即不使用async:false)。

3 个答案:

答案 0 :(得分:1)

又快又脏:

$.ajax({
    url: 'ajax_' + pages[i],

    context: i, // set `this` to `i` in the callback

    success: function(data) {
        // `this` is the correct, "frozen" `i`
        $('<div id="' + pages[this] + '">' + data + '</div>').appendTo('div.content');
    }
});

请注意,this始终强制转换为对象,例如new Number(2)而不是2。然而,它们可用于访问数组索引。

有更简洁的方法可以做到这一点,比如创建一个闭包,但这对你来说可能没问题(例如,如果你没有在回调中使用this进行其他任何操作)。

答案 1 :(得分:0)

您应该始终在for循环变量中使用var关键字来正确地限定它们。否则,这个循环正在访问一个名为i的全局变量,它可能会或可能不会与另一个循环冲突。

但这并不是解决您遇到的确切问题的方法。您需要缓存对当前页面的引用,并在ajax响应中使用它。

for ( var i = 0; i < pages.length; i++ ) {
  var page = pages[i];
  $.ajax({
    //async:false makes it work but it slows things down too much
    url: 'ajax_' + page,
    success: function(data) {
      $('<div id="' + page + '">' + data + '</div>').appendTo('div.content');
      }
  });
 }

答案 2 :(得分:0)

JavaScript有一种称为词法范围的东西,它与大多数人都熟悉的块范围不同。在JS中,为了给出一个新的范围,它必须在另一个函数内部,而不仅仅是花括号{}。

async:false工作的原因是因为你强迫它在继续之前等待响应,这可以避免你的范围问题。

试试这个:

for ( i = 0; i < pages.length; i++ ) {
    $.ajax({
        //async:false makes it work but it slows things down too much
        url: 'ajax_' + pages[i],
        success: (function(index){ 
              return function(data) {
                  $('<div id="' + pages[i] + '">' + data + '</div>').appendTo('div.content');
              };
        })(i)
    });
}