3

I am using jQuery getScript to load X amount of js files into my page. Each of those JS pages has an AJAX call in it that fetches data from the database.

I am using the .done method on getScript to see when all of the files have been loaded but I need to wait until all of the AJAX calls have been completed as well.

How can I go about waiting for the AJAX calls to finish in the included files via getScript before doing something?

$.getMultiScripts(moduleIncludes, 'includes/js/modules/').done(function() {
    // All of the JS files have been included but we need to wait until those files have finished their AJAX call.     
});

// Get array of JS scripts to load
$.getMultiScripts = function(arr, path) {

  var _arr = $.map(arr, function(scr) {
      return $.getScript((path || "") + scr);
  });

  _arr.push($.Deferred(function(deferred) {
      $(deferred.resolve);
  }));

  return $.when.apply($, _arr);
}
Rob
  • 14,746
  • 28
  • 47
  • 65
SBB
  • 8,560
  • 30
  • 108
  • 223
  • Make all the procedures write their finish state somewhere. Then you need to query that "somewhere" (the server, the localStorage, or whatever) in order to check if all the procedures have finished. – pah Jul 03 '16 at 03:55
  • @threadp How would I go about waiting or checking on the status of something like this? – SBB Jul 03 '16 at 03:58
  • Install a `setTimeout` handler that both checks for completion and, if everything is complete (loaded), execute further code. – pah Jul 03 '16 at 04:00
  • @threadp Thanks for the suggestion. I will keep it in mind but will continue to look for a more stable solution. – SBB Jul 03 '16 at 04:07
  • If you know the number of files you can use a counter. – Ismail RBOUH Jul 03 '16 at 04:18
  • What is purpose of `_arr.push($.Deferred(function(deferred) { $(deferred.resolve); }));`? – guest271314 Jul 03 '16 at 04:40
  • @guest271314 - http://stackoverflow.com/a/11803418/2628921 – SBB Jul 03 '16 at 04:41
  • Are you using any other promise libraries other than jquery? – KevBot Jul 03 '16 at 04:44

1 Answers1

5

You can use .ajaxStop()

Whenever an Ajax request completes, jQuery checks whether there are any other outstanding Ajax requests. If none remain, jQuery triggers the ajaxStop event.

$(document).on("ajaxStop", function() {
  // do stuff when all `$.ajax()` call have complete
  $(document).off("ajaxStop")
});

$.getMultiScripts(moduleIncludes, 'includes/js/modules/').done(function() {
    // All of the JS files have been included but we need to wait until those files have finished their AJAX call.     
});

An alternative approach would be to use $.when.apply() twice. That is, push ajax calls into a second array

"module1.js"

data.push($.get("/path/to/module1-resource"))

var modules = ["module1.js", "module2.js", "module3.js"];
// declare global `data` array
data = [];

$.getMultiScripts = function(arr, path) {

  var _arr = $.map(arr, function(scr) {
      return $.getScript(scr)
  });

  return $.when.apply($, _arr.concat($.when()))
}

$.getMultiScripts(arr)
.then(function() {
  console.log("getScript calls", arguments)
  $.when.apply($, data).then(function() {
    console.log("ajax calls", arguments)
  })
});

plnkr http://plnkr.co/edit/si2EsUZOciOwU4nAPlS9?p=preview

guest271314
  • 1
  • 15
  • 104
  • 177