jQuery AJAX调用for循环

Edg*_*dge 19 ajax jquery loops

我是新手使用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');
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

为了简单地说,我有一个包含链接列表的页面.我希望遍历链接并让AJAX处理每个链接页面的内容,并报告该页面是否包含指定的内容.

我遇到的问题是用于遍历linkList的[i]的值总是为6,它永远不应该是.我假设我需要传递一些数据,以便当.done最终触发时,它从AJAX首次触发时知道它的[i]值,而不知道.done在稍后触发时的值[i].

我如何确保.当首次调用AJAX时,done知道它的[i]值?

Ama*_*dan 43

最简单的方法是使用闭包.每当你在循环中有异步时,它都是一样的.

for (var i .....) {
  asynchronousFunction(function() {
    use(i);
  }
}
Run Code Online (Sandbox Code Playgroud)

在此伪代码片段中,内部函数捕获由引用的存储位置i.循环运行,i增量到它的最终值,然后异步回调开始被调用,所有这些都查找完全相同的位置(不是值).

一般的解决方案是:

for (var i .....) {
  (function (i) {
    asynchronousFunction(function() {
      use(i);
    });
  })(i);
}
Run Code Online (Sandbox Code Playgroud)

即将循环的全部内容包装在自执行函数中.

这里,outer 的i传递给包装自执行匿名函数; 异步回调捕获此唯一值的位置.通过这种方式,每个异步都获得自己的值,在调用自执行函数时确定.

  • 所以这就是关闭的重点 (6认同)
  • 添加(function(i){CODE})(i); 包装器工作得很好,现在代码以预期的结果运行.谢谢! (4认同)

Aru*_*hny 13

问题评论部分中的链接告诉您代码中出了什么问题......但是您可以获得比之前解释的更好的解决方案.

尝试$ .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');
        }
    });
})
Run Code Online (Sandbox Code Playgroud)

如果它是一个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');
        }
    });
})
Run Code Online (Sandbox Code Playgroud)