0

I'm trying to build a list of ajax requests to be fed into the $.when() method, so I can do something when all requests are finished (like this answer exemplifies: https://stackoverflow.com/a/24050887/1952996 ).

I came up with this code (jsfiddle):

function getUserData(username){
    return $.ajax({
     url:"/echo/json/",
        data:{json: $.toJSON({"username": username}),
                delay: 3},
        type:"POST",
        success:function(response)
        {
         console.log(response);
        }
    });}

  var userList = ["userA", "userB"];

  var userRequests = [];

  userList.forEach(function(u){
    userRequests.push(getUserData(u));
  })

When I run this, I see that the data gets logged in the console. Why is that? I thought the way i'm building the ajax request i'm returning the ajax defered object. And then I try to store this objects in the userRequests. But these should not be being called already. What am I missing?

Community
  • 1
  • 1
zelite
  • 1,478
  • 16
  • 37
  • 1
    `getUserData(u)` will invoke `ajax-call` and will return `deferred-object` data could be accessed using `then/done` handlers... – Rayon Aug 16 '16 at 06:20
  • So, it seems I clearly had no idea what was going on. But your comment provides me an important bit of information. The ajax call is made immediately on `getUserData(u)` and any side effect of the success function will take place after that request is complete. – zelite Aug 16 '16 at 06:35

1 Answers1

1

jQuery.ajax is designed in a way that it makes an AJAX call when called, and returns AJAX deferred object.

Your code is absolutely similar to the following:

function getUserData(username){
  var result = $.ajax({
    url: "/echo/json/",
    data: { json: $.toJSON({"username": username}), delay: 3 },
    type: "POST",
    success: function(response)
    {
      console.log(response);
    }
  });

  return result;
}

It clearly shows that a request is made at the moment of function call.
You can now use $.when to wait until all requests are completed.

P.S. By the way, you can replace your forEach:

var userList = ["userA", "userB"];

var userRequests = [];

userList.forEach(function(u){
    userRequests.push(getUserData(u));
});

with a shorter version using map:

var userList = ["userA", "userB"];    
var userRequests = userList.map(getUserData);
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101