1

I'm having some problems with the ajax async. I have an array then loop through the array to make an ajax call, if success the ajax will return an xml string, i'll use it to fill in an table and update process bar. I use async:false it works fine on Firefox, but it's not work properly on Chrome. I also tried to use $.ajax().done(), but it's not affect at all.

Is there anyway to get the responsed xml string when ajax call finish then the next loop will run?

for (var i = 0; i <= arr.length; i++){
    $.ajax({
        url: '',
        data: '',
        async: false
    }).done(function(xml) {
       //get xml string to handle and put it into some table as contents
    });
    //Then go to next loop
}
3
  • 3
    Truly synchonous AJAX is deprecated, and for good reason. Nothing should ever block the UI thread. Read into async/await and await the call. Note that it still won't be synchronous, and will never be, and you need to adjust the remaining code accordingly. Commented Aug 5, 2020 at 8:09
  • Using await here is distinctly suboptimal: There's no dependency of request 2 on request 1 so running them serially instead of in parallel will just be slow. Commented Aug 5, 2020 at 8:23
  • I have tried using async/await, and it's really helpful to solve my problem. Thanks so much @CherryDT Commented Aug 6, 2020 at 6:47

3 Answers 3

5

Don't try to make asynchronous code synchronous. You will lock up the event loop and get a nasty performance penalty.

Make the requests in parallel. Collect the promises in an array. Use Promise.all to determine when they have all completed.

Then you can extract the data from them and do what you will with it.

For example:

const baseUrl = "https://jsonplaceholder.typicode.com/users/";
const userIds = [1,2,3,4,5];

const completeUrls = userIds.map( id => `${baseUrl}${id}` );
const promises = completeUrls.map( url => jQuery.ajax({url}) );
const collectedDataPromise = Promise.all(promises);

collectedDataPromise.then( data => {
    const names = data.map( user => user.name );
    const ul = $("<ul />");
    names.forEach( name => {
       ul.append( $("<li>").text(name) );
    });
    $("body").append(ul);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Sign up to request clarification or add additional context in comments.

5 Comments

the data to post not only contain the id as your example, it's contain like a string of GET as params
@StevenDang — As you said, this is just an example. The specifics of what the requests look like isn't relevant.
So if i try this way, i don't have to use the for anymore, right?
Correct. This uses map to perform the iteration (and put the results in an array).
Finally, i decied to use async/await to solve problem as i answered above :D
-1

If you have to update data in each iteration, you can use some string and update in in .done().

Try it with recursion like this:

var counter = arr.length;

function callAjax() {
  if (counter) {
    $.ajax({
      url: '',
      data: ''
    })
    .done(function(xml) {
      //get xml string to handle and put it into some table as contents
      counter--;
      callAjax();
    });
  }
}

2 Comments

The question explicitly wanted to avoid async: false
@Quentin I am sorry, I pasted the ajax call as it was in the question. The code I updated should work, asynchronously.
-1

Finally, i got my own solution that i use the async/await to make sense.

async function ajaxGetData(){
    return $.ajax({
               url: '',
               data: ''
          }).then(response => response.data);
}

async function hanldeResponse(){
   var arr = [1,2,...];
   for(var i = 0; i < arr.length; i++){
       let res = await ajaxGetData();
       //some code to handle the response with res variable
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.