我是使用AJAX的新手,我正在编写一个用户脚本,它将在页面上处理一堆链接并为每个链接进行AJAX调用。
for (var i = 0; i < linkList.length; i++)
{
$.ajax({
url: linkList[i].getAttribute("href"),
cache: false
}).done(function( html )
{
var hasAppended = false;
if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended)
{
hasAppended = true;
var id = linkList[i].getAttribute("href").substring(linkList[i].getAttribute("href").indexOf('='));
$( "#links a[href*='" + id + "']" ).append(' THIS PAGE CONTAINS SPECIFIED DATA');
}
});
}
为了简单地说,我有一个包含链接列表的页面。我希望遍历链接并让AJAX处理每个链接页面的内容,并报告该页面是否包含指定的内容。
我遇到的问题是用于遍历linkList的[i]的值总是为6,它永远不应该是。我假设我需要传递一些数据,以便当.done最终触发时,它从AJAX首次触发时知道它的[i]值,而不知道.done在稍后触发时的值[i]。
我如何确保。当首次调用AJAX时,done知道它的[i]值?
答案 0 :(得分:41)
最简单的方法是使用闭包。每当你在循环中有异步时,它都是一样的。
for (var i .....) {
async(function() {
use(i);
}
}
在此伪代码段中,内部函数捕获i
引用的存储位置。循环运行,i
递增到其最终值,然后异步回调开始被调用,所有这些回调都查找完全相同的位置(而不是值)。
一般解决方案是:
for (var i .....) {
(function (i) {
async(function() {
use(i);
});
})(i);
}
即。将循环的全部内容包装在一个自执行的函数中。
这里,外部i
的值被传递到包装自执行匿名函数中;异步回调捕获此唯一值的位置。通过这种方式,每个异步都获得自己的值,在调用自执行函数时确定。
答案 1 :(得分:12)
问题评论部分中的链接会告诉您代码中出了什么问题......但是您可以获得比之前解释过的更好的解决方案。
尝试$.each()遍历列表(假设它是一个数组),以便传递的回调将为每次迭代创建一个单独的闭包
$.each(linkList, function (i, item) {
$.ajax({
url: item.getAttribute("href"),
cache: false
}).done(function (html) {
var hasAppended = false;
if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) {
hasAppended = true;
var id = item.getAttribute("href").substring(item.getAttribute("href").indexOf('='));
$("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA');
}
});
})
如果是jQuery对象,则使用.each()
linkList.each(function (i, item) {
var $item = $(item),
href = $item.attr("href");
$.ajax({
url: href,
cache: false
}).done(function (html) {
var hasAppended = false;
if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) {
hasAppended = true;
var id = href.substring(href.indexOf('='));
$("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA');
}
});
})