web-dev-qa-db-ja.com

jQuery AJAX forループの呼び出し

私は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が最終的にトリガーされると、when AJAX最初にトリガーされたときの[i]値であり、[d] when .doneの値ではない]後でトリガーします。

AJAXが最初に呼び出されたときに、.doneが[i]値であることを認識できるようにするにはどうすればよいですか?

19
Edge

最も簡単な方法は、クロージャーを使用することです。ループ内に非同期のものがある場合は常に同じです。

for (var i .....) {
  async(function() {
    use(i);
  }
}

この擬似コードスニペットでは、内部関数はiによって参照されるストレージの場所をキャプチャします。ループが実行され、iが最終値まで増加し、非同期コールバックが呼び出され始め、それらすべてがまったく同じlocation(値ではない)を検索します。

一般的な解決策は次のとおりです。

for (var i .....) {
  (function (i) {
    async(function() {
      use(i);
    });
  })(i);
}

つまり、自己実行機能でループの内容全体をラップします。

ここでは、外部iの-​​が、ラッピング自己実行匿名関数に渡されます。この一意の値の場所は、非同期コールバックによって取得されます。このようにして、各非同期は、自己実行機能が呼び出されたときに決定される独自の値を取得します。

42
Amadan

質問のコメントセクションにあるリンクは、コードの何が問題なのかを示しています。

$。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');
        }
    });
})
12
Arun P Johny