Search code examples
javascriptjqueryarrays.when

Why do functions execute when in array but dont when used with jquery 'when'


I am trying to pass dynamic functions to the 'when' statement but when the 'when' is commented out, the functions still get called from the array.

multiAjaxCalls();
function multiAjaxCalls()
{
      var deferParams = [];
      var numOfAjaxToCall = 2; //could be 1 or 2
      if (numOfAjaxToCall === 1) {
            deferParams = [ajax1('1')];
      }
      else if (numOfAjaxToCall === 2) {
            deferParams = [ajax1('1'), ajax1('2')];
      }

      //If this is commented out then the function(s) in the array above still execute
      //If this is NOT commented out, the function only executes once
      $.when.apply($, deferparams).then(
          function () {
            console.log("all ajax calls have been completed, combination of data can happen now.");
            var objects = arguments;
            console.log(objects);
          },
          function (event) {
              console.log("failed in when ", event);
          }
      );

      function ajax1(posnum)
      {
            return ajaxCommon('https://jsonplaceholder.typicode.com' + '/posts/' + posnum);
      }
      function ajax2(posnum)
      {
            return ajaxCommon('https://jsonplaceholder.typicode.com' + '/posts/' + posnum);
      }

      function ajaxCommon(siteURL)
      {
            console.log("starting site url query: ", siteURL);
            return $.ajax({
                  url: siteURL,
                  method: 'GET'
            })
                  .done(function (data)
                  {
                        //console.log("DONE", data);
                        return data;
                  })
                  .fail(function (data)
                  {
                        //console.log("failed INSIDE AJAX URL:", siteURL, "Data: " , data);
                        return data;
                  })
      }
}

The console log i get from the above happens once (which is what i expect):
starting site url query: https://jsonplaceholder.typicode.com/posts/1
starting site url query: https://jsonplaceholder.typicode.com/posts/2

If I comment out the 'when' block so that none of the functions in the array execute anymore, I get the same output in console which means that the functions in the array are still executing.

Why is it that the functions in the array executes once when using the 'when' but still execute when that block is commented out? Also, if there is a better way of working with dynamic functions with the 'when' please let me know.

Thank you.


Solution

  • Instead of this:

    deferParams = [ajax1('1'), ajax1('2')];
    

    do this:

    deferParams = [() => ajax1('1'), () => ajax1('2')];
    

    In the first you are actually executing the function when passing them into the array

    Edit:

    To make this work I have done a bit of a refactor on your code:

    function getPost(postNum) {
      console.log('Calling with', postNum);
      return ajaxCommon('https://jsonplaceholder.typicode.com' + '/posts/' + postNum);
    }
    
    function ajaxCommon(siteURL) {
      console.log("starting site url query: ", siteURL);
      return $.ajax({
        url: siteURL,
        method: 'GET'
      });
    }
    
    function multiAjaxCalls() {
      var numOfAjaxToCall = 2; //could be 1 or 2
    
      var posts = [];
      for (var i = 0; i < numOfAjaxToCall; i++) {
        posts.push(i);
      }
    
      $.when.apply(null, posts.map(p => getPost(p)))
        .then(function () {
          console.log("all ajax calls have been completed, combination of data can happen now.");
          var objects = arguments;
          console.log(objects);
        })
        .fail(function(e) {
            console.log('A call failed', e);
        });
    }
    

    To fix it, instead of passing an array of executed functions in to the apply, I called them in the apply by using map. Which does something similar but only when the when is actually being called.

    Here is a fiddle: https://jsfiddle.net/bqpu2wdm/2/