Why is my javascript / jquery not being executed sequentially?

I have a button attached to a click handler - this makes one or more AJAX calls, depending on the number of elements in the array. I use the blockUI jquery plugin to display a message when ajax calls are made, then show the results and delete the blockUI message by calling $ .unblockUI () ;.

Problem: For some reason, no matter how many times I want the ajaxCall function to execute, after the ajax FIRST call is completed, the messaging is deleted, although the loop continues to run, and the results are displayed correctly in #result div I want the full number of iterations of the loop to complete before deleting the messaging, but it looks like it is not running sequentially. Here is the code in question:

$("#myButton").live("click", function(){ $.blockUI({ message: '<img src="new_loader.gif" /><h2>Getting Config Files</h2><small>Please be patient.</small>', css: { border: 'none', padding: '15px', backgroundColor: '#FFF', '-webkit-border-radius': '10px', '-moz-border-radius': '10px', color: '#000' } }); for (var i=0; i< myArray.length; i++) { ajaxCall(myArray[i]); } $("#results").show('slow'); $.unblockUI(); return false; }); 

Is there any explanation why the code AFTER the loop is executed, although the loop is not yet complete? Any help is appreciated! Thanks.

+4
source share
3 answers
  ajaxCall(myArray[i]); 

runs asynchronously , so the method starts in a loop, but the execution takes a little longer, thus ending after the rest of the code is completed.

A good way to deal with this behavior is in this article: Chaining chains of asynchronous methods in JavaScript

+4
source

Regardless of what ajaxCall() does, if it creates an XMLHttpRequest asynchronously, this is the correct behavior. An Ajax request does not block by default, I think that is why your code after your loop is executed immediately.

One of the possible ways to solve this problem is to create a counter variable, which increases with every call from ajaxCall() and decreases in each complete handler (XHR Readistate 4 file). When this counter reaches zero, you must execute your code after the loop.

 function increase() { // goes into your `ajaxCall()` or `beforeSend` callback mynamespace.requests++; } function decrease() { // goes into your `complete` callbacks if(--mynamespace.requests) { $("#results").show('slow'); $.unblockUI(); } } 
+2
source

I assume ajaxCall is asynchronous? This will cause the code to not lock in the loop, ending the loop substantially and then progressing.

What you can do is provide a callback function with a counter to check if all ajax calls have completed.

 var count = arr.length - 1; for(var i = 0; i < arr.length; i++) { ajaxCall(arr[i], function () { if(--count == 0) { /* All AJAX calls complete, continue execution */ } }); } 
+1
source

Source: https://habr.com/ru/post/1337825/


All Articles