所以我用javascript编写了这段代码:
// Additional initialization code such as adding Event Listeners goes here
FB.api('593959083958735/albums', function(response) {
if(!response || response.error) {
// render error
alert("Noo!!");
} else {
// render photos
for(i=0; i<response.data.length; i++){
var albumName = response.data[i].name;
var albumCover = response.data[i].cover_photo;
var albumId = response.data[i].id;
console.log(albumName);
FB.api( albumCover, function(response) {
if(!response || response.error) {
// render error
alert("Noo!!");
} else {
// render photos
$("ul").append('<li>'+
'<a href="testFile.HTML" data-transition="slidedown">'+
'<img src= "' + response.picture + '" />'+
'<h2>' + albumName + '</h2>'+
'<p> Test Paragraph</p>'+
'</a>'+
'</li>')
.listview('refresh');
}
});
}
}
});
我正在使用facebooks javascript API,将facebook页面的相册导入我的jquery移动页面并将它们放入listView。如您所见,我动态创建listView。 listView的缩略图为专辑coverPhoto和标题,专辑名称。
然而,这里有些可怕的错误。可以看到上面代码的结果here
缩略图都正确但相册名称错误。在每个单元格中,我获得最后一个专辑名称。当我看到我的代码中的console.log(albumName)时,我得到的所有名称都是正确的。但在第二次调用FB.api时,"albumName"
变量只保留最后一个专辑名称。
知道这里发生了什么吗?它确实让我疯狂......
答案 0 :(得分:2)
看起来你有着名的i for loop问题,你只能引用i。
for (var i = 0; i < response.data.length; i++) { //added the var here
(function (i) { //created a function
var albumName = response.data[i].name;
var albumCover = response.data[i].cover_photo;
var albumId = response.data[i].id;
console.log(albumName);
FB.api(albumCover, function (response) {
if (!response || response.error) {
// render error
alert("Noo!!");
} else {
// render photos
$("ul").append('<li>' +
'<a href="testFile.HTML" data-transition="slidedown">' +
'<img src= "' + response.picture + '" />' +
'<h2>' + albumName + '</h2>' +
'<p> Test Paragraph</p>' +
'</a>' +
'</li>')
.listview('refresh');
}
});
})(i); //call the function with i
}
答案 1 :(得分:2)
问题实际上不是i
,而是albumName
。
大多数JavaScript引擎都非常宽容,允许您多次使用var
关键字声明相同的变量。这就是你在这里做的事情。重要的是要注意 for
关键字不会引入新范围;因此,当您(重新)在循环中声明每个变量(albumName
,albumCover
和albumId
)时,您将覆盖先前存储在同一变量中的值。
这回过头来咬你,因为你传递给FB.api
的回调关闭了这些局部变量,并且(显然)异步执行。当回调实际运行时,for
循环已完成,并且这些变量都设置为它们的最后一个值。
当然,例外是albumCover
,正如您已经观察到的那样(您说缩略图都是正确的)。那是因为您同步将此值传递给FB.api
;即,你在循环中传递 ,因此它不会被关闭。
为了更好地理解JavaScript中的闭包,请参阅How do JavaScript closures work?
要明确:epascarello's answer应该为您解决问题。在匿名函数中包含逻辑会引入一个新范围(一种可用于各种场景的有用技巧),因此albumName
等的值将被关闭每次回调都不同。我只是想指出,导致问题的不是i
本身(因为你的回调根本没有关闭i
)。