我有一个函数,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
,而不是预期的。
因此,当创建 3 个占位符并且 ajax 结果进来时,它们都引用#albumplaceholder-3
而不是各自的占位符。
如何解决这个问题?提前谢谢。
编辑:感谢您的建议,但我最终解决了这样的问题:
我不是每次都调用 fetchAlbum()
函数,而是设置如下元素:
<div class="image-album" data-albumid="IMGURID"></div>
并在最后使用$('.image-album).each(function(){ ... })
,分别遍历每个占位符,读取data-albumid
属性,发出AJAX请求等等。这将保持正确的闭包。
恭喜你,你被关闭难住了!这将使您进入下一个级别的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.
尝试更改,
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');
使用 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