正确引用延迟 AJAX 调用中的变量
Referencing a variable in a delayed AJAX call correctly
我有一个函数,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
- 从带参数的字符串变量调用函数中的函数
- 将方法从控制器注入到未使用右变量调用的指令
- 为什么可以对整数变量调用toString(),而不能对文字数字调用
- 我可以对变量调用“.log”吗?
- 是否可以对超出范围的 setInterval 变量调用 clearInterval 方法
- 对模板中的胡子变量调用方法
- 使用不同的变量调用递归函数
- Jquery中的变量调用
- 将循环变量调用到自动压缩选择中
- 如何在 jquery 中用变量调用变量
- jQuery,从变量调用数组对象的一部分
- 在 AngularJS 中使用绑定变量调用控制器方法
- 如何使用变量调用对象及其方法
- 是否可以对变量调用jquery函数
- Android:从javascript传递变量调用Java中的函数
- 带有变量调用的谷歌地图API实现
- 无法对数字变量调用 toFixed
- 如何将嵌套的全局或本地jquery变量调用到html中
- Javascript:如何通过变量调用函数并传递参数
- 对字符串变量调用toUppercase()