我有一系列网址,以及我从外部提取的一系列数据。 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
数组的第一个元素。我可以将数字更改为任何其他有效索引,它可以工作。但是 second 日志始终打印undefined
。我最初从第二个循环中抓取了url,但我把它拿出来以防万一它被证明是一个异步错误或其他东西。 urls
初始化为Array
,而不是Object
。从成功函数中取出第二个注销(并进入for循环的主要范围)使其按预期执行。我很乐意把它搞砸到以某种方式搞砸它的ajax请求,但是为什么第一个日志按预期执行?
有什么想法吗?
答案 0 :(得分:2)
$ .ajax是异步的,这意味着当回调(成功)运行时,循环已经完成运行并且现在设置为children.length
访问网址[i],等于网址[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 );
}
答案 1 :(得分:1)
对Pantelis的答案+1,虽然只是一个有点迂腐的评论:没有真正需要在IIFE中包装整个 ajax调用,只有成功回调需要引用“ 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)
});
}
答案 2 :(得分:0)
这是因为在最终调用成功函数时我未定义。您需要将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)
});
}
这里,为每次迭代生成的成功函数略有不同,因为它记录了不同的值。