2

我有一组 URL,以及一组要从外部提取的数据。URL 和数据完美地一一对应。我尝试这样做:

for (var i = 0; i < children.length; i++) {
    urls.push(children[i].data.url); 
}

for (var i = 0; i < children.length; i++) { 
    $.ajax({
         url: DATA_SOURCE,
         dataType: "jsonp",
         success: function (data2) {                           
             console.log(urls[0]);
             console.log(urls[i]);
         }
    });                        
}

第一个日志总是打印urls数组的第一个元素。我可以将数字更改为任何其他有效索引并且它可以工作。然而,第二个日志总是打印undefined。我最初是从第二个循环中获取 url,但我把它拿出来以防万一它被证明是一个异步错误或什么的。urls被初始化为一个Array,而不是一个Object。将第二个日志从成功函数中取出(并进入 for 循环的主要范围)使其按预期执行。我很乐意将它归结为 ajax 请求以某种方式搞砸了它,但是为什么第一个日志会按预期执行呢?

有任何想法吗?

4

3 回答 3

2

$.ajax 是异步的,这意味着当回调(成功)运行时,循环已经完成运行,现在设置为 children.length

访问 urls[i],等于 urls[children.length,因此是未定义的。

一个简单的解决方法是为每次迭代创建范围

for (var i = 0; i < children.length; i++) { 
  (function( index ) {
    $.ajax({
       url: DATA_SOURCE,
       dataType: "jsonp",
       success: function (data2) {                           
         console.log(urls[ index ]);
        }
    }); 
  })( i );                       
}
于 2012-10-18T07:12:56.360 回答
1

对 Pantelis 的回答 +1,虽然只是有点迂腐的评论:实际上不需要将整个ajax 调用包装在 IIFE 中,只有成功回调需要引用 的“当前”i,所以这样就可以了:

for (var i = 0; i < children.length; i++)
{
    $.ajax({
       url: DATA_SOURCE,
       dataType: "jsonp",
       success: ((function( index ) 
       {
           return function (data2)
           {
               console.log(urls[ index ]);
           };
       })(i)
    });
}
于 2012-10-18T07:24:47.140 回答
0

这是因为最终调用成功函数时 i 未定义。您需要将 i 的当前值传递给您正在生成的成功函数。

for (var i = 0; i < children.length; i++) { 
    $.ajax({
         url: DATA_SOURCE,
         dataType: "jsonp",
         success: (function (count) {
             return(function(data2){console.log(urls[0]); console.log(urls[count]);});        
         })(i)
    });                        
}

在这里,为每次迭代生成的成功函数略有不同,因为它记录了不同的值。

于 2012-10-18T07:12:58.400 回答