我正在处理的程序中有一个包含大量网址的数组,例如:
var urls = ["http://www.url.com/page1", "http://www.url.com/page2", "http://www.url.com/page3"];
然后我遍历这个数组,以便根据每个网址运行一些代码:
for (var i = 0; i < urls.length; i++) {
$.get(urls[i], function(response) {
console.log(urls[i]);
});
我使用$ .get从网站上的另一个页面中提取数据,我的问题是console.log显示未定义?更奇怪的是,如果我将url [1]或任何值作为数字传递到console.log中,那么它是否会从数组中返回url?
此外,如果我只记录当前的循环索引,如
console.log([i]);
然后它只输出3次,三次。
答案 0 :(得分:1)
您需要一个闭包才能保留 i 变量。变量的竞争是全局的,当for结束时,值是urls.length + 1.相反,如果你在IIFE中关闭代码,则保留变量的值,因为它获得了一个函数范围。
使用现代浏览器,您可以使用
let而不是var:声明一个块范围局部变量,可选择将其初始化为一个值。
变化:
for (var i = 0; i < urls.length; i++) {
$.get(url[i], function(response) {
console.log(urls[i]);
});
要:
for (var i = 0; i < urls.length; i++) {
(function (i) {
$.get(url[i], function(response) {
console.log(urls[i]);
});
})(i);
答案 1 :(得分:1)
您有异步问题。调用内部函数时,i === urls.length
因为外部for
循环已经完成。
for (var i = 0; i < urls.length; i++) {
// The anonymous function won't get called until the for loop completes
// and you get a response back from the url.
$.get(urls[i], function(response) {
// When this finally gets called, the for loop has already completed
// and i === urls.length, AKA undefined
console.log(urls[i]);
});
}
您可以使用let
来解决问题:
for (var i = 0; i < urls.length; i++) {
// This will scope the variable to this for loop.
let url = urls[i];
$.get(url, function(response) {
console.log(url);
});
}