0

I have a php script that processes a lot of data (process_data.php). Every 2 seconds it "pauses" and outputs the current progress status, e.g. "Processed 8% ...". When the process is complete it outputs "eod".

I have now written the HTML + jQuery code below. It iterates by repeatedly making synced Ajax calls to process_data.php. The progress response is copied to the ajax-div. The iterations continues until the "eod" is received.

The problem is that no response will be visible to the user until the entire iteration is completed. I guess that I need to force some "flush buffer" or updating the page/element.

If I enables the alert-line (uncomment it), the output becomes visible after each iteration.

How can I force the progress text to be visible after each iteration?

$(document).ready(function() {
  do {
    eod = false;
    $.ajax({
        url: "process_data.php",
        async: false,
        success: function(progressTxt, statusTxt, xhr) {
          if (statusTxt == "success") {
            if (progressTxt == "eod") {
              eod = true;
            } else {
              $("#ajax-div").html(progressTxt);
            }
          }
        });

      // alert("Click for next...");  <-- If I uncomment this line the results are shown for each iteration...
    }
    while (res != "eod")
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="container">
  <div id="original-text">Processing data... Current progress is:</div>
  <div id="ajax-div"> </div>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Gowire
  • 1,046
  • 6
  • 27
  • Both the do/while loop and the `async:false` will block the browser from updating the UI while they are in process. If you want to update the UI while these are happening I'd suggest you amend the logic to use callbacks and/or promises, something like this: https://stackoverflow.com/q/20291366/519413. That being said, I would also state that making AJAX requests in a loop is generally a bad thing to be doing. You seem to be doing this to track the server state. As such I'd suggest researching the Observer Pattern and using WebSockets instead. – Rory McCrossan Oct 16 '20 at 11:25

1 Answers1

1

Don't loop ajax and don't use async:false

This will work

let eod = false;

function poll() {
  if (eod) return; // stop

  $.ajax({
    url: "process_data.php",
    success: function(progressTxt, statusTxt, xhr) {
      if (statusTxt == "success") {
        if (progressTxt == "eod") {
          eod = true;
         $("#ajax-div").html("Done");
        } else {
          $("#ajax-div").html(progressTxt);
          setTimeout(poll, 1000); // every second. You can change this
        }
      }
    }
  })
};
$(function() {
  poll();
});
mplungjan
  • 169,008
  • 28
  • 173
  • 236