0

I am making 3 get JSON calls in myFunction() that gets called on a button click. 2 of these getJSONs depend on each other for their execution. It basically parses through 10 web pages and collects some data. With this data it will go to another page and collect some other data. I want to display "DONE" at the end of myFunction so the user knows that we have finally got all data and the search operation is complete. However these calls, I think, are asynchronous, so I use deferred objects. But even though I pass all calls to $.when.apply(call1,call2,call3), it displays the "DONE" before any data is printed on the console. Once it prints "DONE", then it starts to print the results. How can I modify my code so that I would be able to display "DONE" only when myFunction has ran completely for all 10 pages and has printed all data on the console.

var call1 = [];
var call2 = [];
var call3 = [];

function myFunction() {
  data3 = [];
  url = ''; // some URL here
  call3.push($.getJSON(url, function(data4) {
    data3 = data4;
  }));
  for (var page = 1; page < 10; page++) {
    (function(page) {
        url = 'http://example.com/' + page;
        call1.push($.getJSON(url, function(data1) {
            for (var num = 0; num < data1.standings.results.length; num++) {
              (function(num) {
                  url = 'http://example.com/' + data1.entry[num];
                  call2.push($.getJSON(url, function(data2) {
                      for (var i = 0; i < 15; i++) {
                        (function(i) {
                            console.log(data3.ele[(data2.p[i].element) - 1].x);
                            return;
                          }
                        })(i);
                    }
                  })
                );
              })(num);
          }
        })
      );
    })(page);
};
$.when.apply(call1, call2, call3).then(function() {
  console.log("DONE");
});
}
Anurag Joshi
  • 300
  • 1
  • 12
  • Please [indent your code properly](http://jsbeautifier.org/). Nobody's gonna work through that. – Bergi Aug 21 '17 at 16:44
  • Yes,done @Bergi ,thank you @brk! – Anurag Joshi Aug 21 '17 at 16:47
  • You don't make 3 `getJSON` calls, you do many of them in nested loops. Your promise structure needs to reflect that. – Bergi Aug 21 '17 at 17:01
  • `$.when` takes multiple promises, not multiple arrays of promises. Have a look at https://stackoverflow.com/q/4878887/1048572 for how to work with arrays. – Bergi Aug 21 '17 at 17:03
  • Never pass callbacks into `getJSON`. Use only `then` for promise chaining. – Bergi Aug 21 '17 at 17:03
  • Thank you for the link and explanation @Bergi, I still seem to have some difficulty in understanding what exactly I need to do. My first thought is that I probably need to change my entire function structure, but is there any other simpler method? Thank You! – Anurag Joshi Aug 21 '17 at 22:02

1 Answers1

0

I was finally able to solve this problem. As mentioned in the comments, we need to chain various promises and the function structure should match the structure of the when command. So, in the function as call1 was pushed first, I need to call the when command for call1 and then nest the subsequent commands and so on.

var call1 = [];
var call2 = [];
var call3 = [];

function myFunction() {
  data3 = [];
  url = ''; // some URL here
  call3.push($.getJSON(url, function(data4) {
    data3 = data4;
  }));
  for (var page = 1; page < 10; page++) {
    (function(page) {
        url = 'http://example.com/' + page;
        call1.push($.getJSON(url, function(data1) {
            for (var num = 0; num < data1.standings.results.length; num++) {
              (function(num) {
                  url = 'http://example.com/' + data1.entry[num];
                  call2.push($.getJSON(url, function(data2) {
                      for (var i = 0; i < 15; i++) {
                        (function(i) {
                            console.log(data3.ele[(data2.p[i].element) - 1].x);
                            return;
                          }
                        })(i);
                    }
                  })
                );
              })(num);
          }
        })
      );
    })(page);
};
$.when.apply($, call1).then(function(){
$.when.apply($, call2).then(function(){
document.getElementsByName('output')[0].value+="Search Completed"+'\r\n';
});
});
}
Anurag Joshi
  • 300
  • 1
  • 12