Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery AJAX calls in for loop [duplicate]

Tags:

I'm new to using AJAX, and I'm writing a userscript that will process a bunch of links on a page and make AJAX calls for each one.

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');         }     }); } 

To try to put it simply, I have a page with a list of links. I wish to iterate through the links and get AJAX to process the contents of each of the links pages, and report back if that page contains something specified.

The issue I'm having is the value of [i] used to iterate through the linkList is always 6, and it should never be. I'm assuming I need to pass some data so that when .done finally triggers, it knows its [i] value from when AJAX first triggered and not the value of [i] when .done triggers later.

How do I go about ensuring .done knows it's [i] value when AJAX is first called?

like image 268
Edge Avatar asked Feb 17 '14 02:02

Edge


1 Answers

The easiest way is to use a closure. Whenever you have something asynchronous in a loop, it is the same thing.

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

In this pseudocode snippet, the inner function captures the storage location referenced by i. The loop runs, the i increments to its final value, and then the async callbacks start getting called, all of them looking up the exact same location (not value).

The general solution is this:

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

i.e. wrap the whole contents of your loop in an self-executing function.

Here, the value of outer i gets passed into the wrapping self-executing anonymous function; this unique value's location gets captured by the async callback. In this way, each async gets its own value, determined at the moment the self-executing function is invoked.

like image 155
Amadan Avatar answered Oct 04 '22 17:10

Amadan