我有一个函数fetchAlbum
,用于设置占位符,发出AJAX请求,并在成功时重新访问其占位符以进行更新。它看起来像这样:
function fetchAlbum() {
albumCounter++;
var albumElement = $('<div/>', { id: 'albumplaceholder-' + albumCounter }).html('Loading...').appendTo('#results');
var callbackID = '#albumplaceholder-' + albumCounter;
imgurJSON = $.ajax({
//...
success : function() {
$(callbackID).html(imgurJSON.responseJSON.data //...);
}
});
}
这一切都有效,但是如果重复调用此函数,则会遇到问题。 AJAX请求的success
函数似乎总是引用最新的callbackID
而不是预期的。{/ p>
因此,当创建3个占位符并且ajax结果进入时,它们都引用#albumplaceholder-3
而不是它们各自的。{/ p>
如何解决这个问题?提前谢谢。
修改:感谢您的建议,但我最终解决了这样的问题:
我不是每次都调用fetchAlbum()
函数,而是设置这样的元素:
<div class="image-album" data-albumid="IMGURID"></div>
最后使用$('.image-album).each(function(){ ... })
,分别浏览每个占位符,读取data-albumid
属性,发出AJAX请求等等。这样可以保持正确的闭合。
答案 0 :(得分:1)
恭喜你,你被closure感到难过!这使您成为下一级JavaScript开发人员。这需要一杯咖啡(它甚至还没有午夜)。
闭包是当一个函数在另一个函数内部时,内部函数使用外部函数中的变量。在您的情况下,AJAX成功处理程序使用albumCounter
。
albumCounter
只有一个值。你没有制作三份副本 - 每份都有自己的连续值 - 就像你期望的那样。当ajax调用回来时,他们都在查看对值的一个引用,而不是它们自己的单个副本。您应该albumCounter
使用自己的参数,例如albumId
,就像其他答案中所建议的那样。
您可以像这样重现行为:
var i = 0;
function outerFunction(){
i++;
function innerFunction(){
setTimeout(function(){
console.log(i);
}, 5000);
};
innerFunction(); //execute the inner function
}
outerFunction();
outerFunction();
outerFunction(); //in 5 seconds, logs the number 3, 3 times
相反,做这样的事情:
function outerFunction(iterator){
function innerFunction(){
setTimeout(function(){
console.log(iterator);
}, 5000);
};
innerFunction(); //execute the inner function
}
for(var i = 0; i < 3; i++){
outerFunction(i); //logs 1, 2, 3 in 5 seconds
}
或者在你的情况下
function fetchAlbum(albumCounter) { //the outer function
var albumElement = $('<div/>', { id: 'albumplaceholder-' + albumCounter }).html('Loading...').appendTo('#results');
var callbackID = '#albumplaceholder-' + albumCounter;
imgurJSON = $.ajax({ //execute the inner function
//...
success : function() { //the inner function
$(callbackID).html(imgurJSON.responseJSON.data //...);
}
});
}
fetchAlbum(1);
fetchAlbum(2); // In other words, something outside of `fetchAlbum()`
fetchAlbum(3); // should oversee which album to fetch.
答案 1 :(得分:0)
使用albumID
作为callbackID
的前缀,也可以使其独一无二并解决您的问题。
var callbackID = '#albumplaceholder-' + albumCounter + "-" + albumID;
var albumElement = $('<div/>', { id: callbackID }).html('Loading...').appendTo('#results');
您还可以添加时间戳,使其更加独特。
但我会建议您依赖ajax
响应,只需使用albumID返回响应并按此处理
success : function(res) {
var id = res.id// {id : albumID}
$(id).html(imgurJSON.responseJSON.data //...);
您明白了,您需要相应地修改var callbackID
答案 2 :(得分:0)
尝试更改,
albumCounter++;
var albumElement = $('<div/>', { id: 'albumplaceholder-' + albumCounter}).html('Loading...').appendTo('#results');
var callbackID = '#albumplaceholder-' + albumCounter;
到
albumCounter++;
var callbackID = '#albumplaceholder-' + albumCounter;
var albumElement = $(callbackID).html('Loading...').appendTo('#results');