-1

I have a problem with getting values in success function (ajax) inside the $.each loop.

I've got something like this:

var test = [];
$.each(images, function(index){
    var formData = new FormData();
    formData.append('image', images[index]);

    $.ajax({
        url: 'http://localhost/admin/api/offers/upload_photo',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        beforeSend: function(){
            console.log(test.length);               
            test.push(images[index]);       
        },
        success: function(){
            console.log(test.length);
        }
    });
});  

And the output of beforeSend works fine (console log: 0, 1, 2), but another one returns three times 3 (console log: 3, 3, 3). The rest works with no problems, I only struggle with it. Is there anyone who is able to help me? Thanks!

BociucH
  • 119
  • 1
  • 1
  • 8
  • 1
    seems like it's doing exactly what it should be. – Kevin B Apr 01 '16 at 19:12
  • It seems that your `each` loop finishes before any of the `success` functions fire. So, by the time `success` fires for one of the iterations, the loop has completed and the length of `test` is three. This might be informative: [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – showdev Apr 01 '16 at 19:12
  • That's why ajax is async :) as its name says :) – Marko Mackic Apr 01 '16 at 19:13
  • This behaviour seems logical and as expected. What did you want the code to do? – Rory McCrossan Apr 01 '16 at 19:22

1 Answers1

0

AJAX requests are asynchronous by default. This means that it sends the request to the server, but doesn't wait for the response to return before continuing with the code. So the $.each() loop sends all three AJAX requests, and executes all their beforeSend: functions, immediately. The success: functions aren't executed until the responses are processed, which won't be until your code returns to the main browser event loop.

Since all the beforeSend: functions are executed before any of the responses are processed, the test array will be filled with all the images when the success functions are executed. So they'll all see test.length == 3.

Barmar
  • 741,623
  • 53
  • 500
  • 612