How to make Multiple ajax requests in a loop return values sequentially?
Asked Answered
D

4

5

I have to make a series of Ajax requests on a loop. Around 100 of them. And each request returns a JSONP variable. I extract data from the JSON and keep appending the value into a div. The problem is that I want the div to be appended with data in the order of function call. i.e sequentially. Now i get a different order everytime i refresh the page depending on the order in which the request completes. Here's my code.

  $.each(elem, function (index, item) {

            $.ajax({
                type: 'post' ,
                url: moviesSearchUrl + '&q=' + encodeURI(item) + '&page_limit=1',
                dataType: "jsonp",
                async: false, 
                success: searchCallback
            });

            function searchCallback(data) {
                var movies = data.movies;

                var markup = index + ': '+   movies[0].title + '<img class=" bord" src="' + movies[0].posters.thumbnail + '" /><br/>';

                $("div.content").append(markup);
            }

        });
});

As i am displaying the value of the index inside the div, everytime i get random orders . 2 4 3 1 7 sometimes and 1 5 2 7 4 sometimes. I even tries async: false . That doesnt help. I read somewhere that JSONP cannot be done with async: false . Please help me out.

Drew answered 11/4, 2012 at 1:57 Comment(0)
L
4

You could use a place-holder.

  $.each(elem, function (index, item) {

            var $placeholder = $('<div>').appendTo("div.content");

            $.ajax({
                type: 'post' ,
                url: moviesSearchUrl + '&q=' + encodeURI(item) + '&page_limit=1',
                dataType: "jsonp",
                async: false, 
                success: searchCallback
            });

            function searchCallback(data) {
                var movies = data.movies;

                var markup = index + ': '+   movies[0].title + '<img class=" bord" src="' + movies[0].posters.thumbnail + '" /><br/>';

                $placeholder.replaceWith(markup);
            }

        });
});
Laughable answered 11/4, 2012 at 2:1 Comment(4)
I tried it, I get only the first value now. Div doesn't get appended with other data.Drew
Sorry my bad. I didnt declare the placeholder variable. It words sequentially now. But i have a new problem. Some of the requests get lost. I get 1-25 movies after that i dont get values for the nest 10 , then i get for the next 10 and something like that. I think there might be a problem with the API limit. Ill look into it. Thanks!Drew
Let me know if you can monitor the traffic, we might be able to find a way to throttle your requests. I usually use firefox's firebug for analysing ajax responses. Is there any way to consolidate the things you're requesting into a single call to the API?Laughable
I can monitor traffic in the Rotten Tomatoes site. I use the Rotten Tomatoes API. Infact i just asked another question regarding this . It would be great if you can help me with that . #10099615Drew
C
9

Don't use a for-loop. Use a recursive function:

var i = 1;

function loadNext(){
    if (i < 5){
        $.ajax({
            type: "GET",
            url: "results/result_html.php?usn="+i+"&resultType="+resultType,
            dataType:"JSON",
            success:function(result){
                finalResult+=result;
                result=result+htmlMessage;
                $("#info").hide();
                $("#result").html(result);              
                $("#usn").attr("placeholder", "Class USN");
                loadNext();
            }
        });
        i++;
    }
}
Codification answered 21/12, 2013 at 6:39 Comment(1)
this will run synchronously. if can run synchronously, better use async:false parameterBekki
L
4

You could use a place-holder.

  $.each(elem, function (index, item) {

            var $placeholder = $('<div>').appendTo("div.content");

            $.ajax({
                type: 'post' ,
                url: moviesSearchUrl + '&q=' + encodeURI(item) + '&page_limit=1',
                dataType: "jsonp",
                async: false, 
                success: searchCallback
            });

            function searchCallback(data) {
                var movies = data.movies;

                var markup = index + ': '+   movies[0].title + '<img class=" bord" src="' + movies[0].posters.thumbnail + '" /><br/>';

                $placeholder.replaceWith(markup);
            }

        });
});
Laughable answered 11/4, 2012 at 2:1 Comment(4)
I tried it, I get only the first value now. Div doesn't get appended with other data.Drew
Sorry my bad. I didnt declare the placeholder variable. It words sequentially now. But i have a new problem. Some of the requests get lost. I get 1-25 movies after that i dont get values for the nest 10 , then i get for the next 10 and something like that. I think there might be a problem with the API limit. Ill look into it. Thanks!Drew
Let me know if you can monitor the traffic, we might be able to find a way to throttle your requests. I usually use firefox's firebug for analysing ajax responses. Is there any way to consolidate the things you're requesting into a single call to the API?Laughable
I can monitor traffic in the Rotten Tomatoes site. I use the Rotten Tomatoes API. Infact i just asked another question regarding this . It would be great if you can help me with that . #10099615Drew
B
3

Something like:

// iterate over your set
$.each(myset, function(i,e){

  // placeholder div (hidden from view until it's populated)
  var $placeholder = $('<div>').hide().appendTo('div.content');

  // make your ajax call
  $.getJSON('/link/to/resource','{date:here}',function(d){

    // insert the content in to the div and re-show it
    $placeholder.text(i + ': ' + d.movies[0].title).show();
  });
});
Blacktop answered 11/4, 2012 at 2:5 Comment(0)
L
0

    const j = 10;
    for (let i = 1; i <= j; i++) {
        // wait for the promise to resolve before advancing the for loop
        await ajaxcall(i);
        console.log(i);
    }
}

function ajaxcall(id){
   return new Promise(function(resolve, reject){
      var sUrl = "https://jsonplaceholder.typicode.com/todos/"+id;

      $.get(sUrl, function(data) {
           alert( "Load was performed."+JSON.stringify(data));
           resolve(data); 
      });
      
   }); 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<button onclick="someFunction()"> Test </button>
Lemay answered 29/11, 2018 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.