Search code examples
jqueryajaxsequential

jQuery sequentially render items fetched from ajax requests


I have a page displaying listings of objects. Each of these listings come from an ajax call. How do I go about making sure they are rendered sequentially?

Ive tried using the technique shown here, but incase one of the requests fails, it rejects the remaining. My data isnt dependant on the previous, so how do I go about modifying the example, and handling errors?


Solution

  • You know, in another post, I wrote this little Resolver class, but I like this idea of piping. I don't know that I like the example so much, but with a little tweaking, I think it'll work just fine. I'll admit, I have yet to test this, though.

    var urls = ["path1","path2","path3"]; // Output from string.split()
    var chain = $.Deferred(); // Create the root of the chain.
    var promise = chain; // Placeholder for the promise
    
    // Build the chain
    jQuery.each(urls,function(index,elem){
        // Pipe the response to the "next" function
        promise = promise.pipe(function(response)
        {
            var myurl = elem; // Get the current part
            var newPromise = $.Deferred();
            $.ajax 
            ({
               type: "GET",
               url: myurl
            }).done(function(data){  
              //these are your normal ajax success function params, IIRC
               //do stuff with response
            }).fail(function(){
               //oops, it failed, oh well
               //do stuff on failure 
            }).always(function() {
               //but always resolve the sequencing promise
               newPromise.resolve();            
            });
            return newPromise;
        })
    });
    
    chain.resolve();
    

    EDIT: here's a JSFiddle with simulated ajax requests http://jsfiddle.net/jfcox/gFLhK/. As you can see, it all sequences up.

    EDIT II: slight tweaks in comments. note you should be able to pass in info to your next promise by passing in whatever to your resolve invocations...

    EDIT III: modified per Dave's suggestion. To further separate concerns, you can use always on the ajax request.