0

I'm totally new to jquery but I have a .each loop that fetches some data using ajax and then updates list elements. Right now the .each loop does all list elements at the same time... I need it to do the first one, wait till its done then do the second one etc. etc. I do NOT want to use delay. I want the loop to actually wait until the data is fetched then move on to the next element. Please no faking it using delay. Here is my code simplified.

$(document).ready(function() {
    $.ajaxSetup({cache:false});
    $('#friendslist li').each(function(index) {
        var post_id = $(this).attr("id")
        $(this).find(".status div").html("<img src='http://www.url.com/image.jpg'/>");
        $(this).find("#replace").load("http://www.url.com/ajaxstuff",{id:post_id});
    })
});

Thanks in advance for the help!

2
  • Why don't you want to load them all asynchronously? Blocking while loading doesn't seem to be a very good idea. And by using a 'delay' I assume you mean using setTimeout or setInterval; that's not 'faking it', that's the way JavaScript works - there is no threading API available to you so you break up your task into smaller pieces and use one of these functions to do it. Commented Mar 14, 2011 at 22:10
  • 1
    The ajax is fetching data that is being collected on the fly by a scrapper I built, there could be a hundred+ items in this list, if they are all executed asynchronously it could crash the website. 100+ requests per person...400+ people a day... probably a bad idea. Commented Mar 14, 2011 at 22:24

4 Answers 4

2

You can set the async option to false if you want the loop to wait on it, which will render the browser un-usable while it is executing.

like this

$.ajaxSetup({cache:false, async:false});
Sign up to request clarification or add additional context in comments.

5 Comments

This will freeze the browser if you have more than just a few fragments to fetch.
"which will render the browser un-usable while it is executing."
And yet you still suggest it?
I'm simply trying to help the OP accomplish his goal, feel free to produce your own answer if you feel there is a better option.
Thank you for your answer, although I probably dont want to go this direction anymore since it does freeze the browser like you mentioned.
2

Set up a queue where you place each of your functions. Call the first function in the queue. When it finishes executing, it should pop the next function off of the queue and execute it, and so on. Do not use synchronous Ajax requests, since this will lock up the browser.

Simplified example:

var queue = [];
queue.push(function(){
    $("#replace").load("somefile.html", function(){
        // Still need to check that another element to pop exists
        (queue.pop())();
    });
});
queue.push(function(){
    $("#replace2").load("somefile2.html", function(){
        // Still need to check that another element to pop exists
        (queue.pop())();
    });
});
(queue.pop())();

Please note that this can be further optimized, and you still need to check that another exists that you can pop and execute. But, it's a start.

3 Comments

Cool can I use this method except with what nate mentioned below, using the "next" so that its more dynamic?
Yep, that is what this does. In the callback for each function, (queue.pop())(); will execute the next one.
since you're using array methods I think you mean var queue = [].
0

You'll need to restructure you code. You to run the next "query" in the callback of the prior query. Since .load will run asynchronously.

Comments

0

Instead of doing an $.each loop, you could simply recursievely call the function again in the load() handler.

function LoadFriends(i) {
    $("#friendslist li:eq(" + i + ")").load('/echo/html/', {
        html: 'Hello!', delay: 1
    }, function() {
        LoadFriends(i+1);
    });
}
LoadFriends(0);

Code Example on jsfiddle.

Putting that with your sample code:

$(document).ready(function() {
    $.ajaxSetup({cache:false});

    function LoadFriends(i) {
        var $li = $("#friendslist li:eq(" + i + ")");

        var post_id = $li.attr("id")
        $li.find(".status div").html("<img src='http://www.url.com/image.jpg'/>");
        $li.find("#replace").load("http://www.url.com/ajaxstuff",{id:post_id}, , 
            function(){
              LoadFriends(i+1);
        });
    }
    LoadFriends(0);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.