Home > Software design >  wait for jQuery getJSON to be complete to continue for loop
wait for jQuery getJSON to be complete to continue for loop

Time:09-26

I have the following 2 functions:

function setPanelTo(panel,id){
  $.getJSON("https://e926.net/posts/" id ".json?_client=" clientname, function( data ) {
    var img = document.createElement("img")
    img.classList.add("panel")
    img.src = data.post.file.url;
    comic.append(img)
  });
}

function getPoolByID(id){
  comic.innerHTML = "";
  $.getJSON("https://e926.net/pools/" id ".json?_client=" clientname, function( data ) {
    for (var x = 0; x < data.post_ids.length; x  ){
      setPanelTo(x,data.post_ids[x]);
    }
  });
}

and when I call the getPoolByID(); function, it populates the 'comic' <div> element with images. However, the images do not appear in the correct order, which slightly undermines the point of a comic. How do I make it so that the images don't load until the previous image has loaded?

Note: I've tried using a table, and while it worked, the images did not wrap when they reached the edge of the page, which is a must have for this.

CodePudding user response:

Use Image Placeholders

There are a few ways to solve the problem. The simplest solution is to modify the code to generate placeholder images and assign each a sequence ID. This ensures that the comic panels are in the correct order. And as the getJSON() for each image completes it updates the image src with the actual url.

Request Throttling

The API documentation says:

E621/E926 have a hard rate limit of two requests per second. This is a hard upper limit and if you are hitting it, you are already going way too fast. Hitting the rate limit will result in a 503 HTTP response code. You should make a best effort not to make more than one request per second over a sustained period.

And your loop to pull images hits this limit, which is why not all of the images are returned. So you may also need to add a timer to the loop to slow down the request rate, but this is outside the scope of the original question.

See related question for ideas: Ways to throttle ajax requests

Run the code snippet to understand how it works:

function setPanelTo(panel,id){

  // Here we create an image placeholder BEFORE calling getJSON().

  comic.innerHTML  = 
  '<img id="id'   id   '" src="https://via.placeholder.com/100" />';

  $.getJSON("https://e926.net/posts/" id ".json?_client=" clientname, function( data ) {
  
    // And then we update each image once we have the actual url
  
    document.querySelector("#id"   id).src = data.post.file.url;
    
  });
}

function getPoolByID(id){
  
  comic.innerHTML = "";  
  
  $.getJSON("https://e926.net/pools/" id ".json?_client=" clientname, function( data ) {
  
    for (var x = 0; x < data.post_ids.length; x  ){
      setPanelTo(x,data.post_ids[x]);
    }

  });
}

// Test
let clientname = "noname";
getPoolByID("30251", "");
img {
  height: 100px;
  width: auto;
  margin: 2px;
  border: 1px solid black;
}
Image source: <a href="https://e926.net/pools/30251" target="_blank">https://e926.net/pools/30251</a>

<div id="comic"></div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  • Related