How can I add a new jquery deferred to existing $ .when?

I'm refactoring a resource loading function that used a traditional callback template instead of using jQuery Deferred.

This function accepts URL arrays, creates a new Deferred object for each resource, creates a $.when Deferred object to view them, and returns the promise of the $.when .

Here is a simplified version of the method:

 theLib = { getResources : function(paths) { var deferreds = []; theLib.isLoading = true; $.each(paths, function(i, path) { // do something with the path, either using getScript // or making a new $.Deferred as needed deferreds.push(/* the deferred object from above comment */); }); theLib.currentDeferred = $.when.apply(null,deferreds).always(function() { theLib.isLoading = false; }); return theLib.currentDeferred.promise(); }; 

It works well.

My problem: in the old script, not only one call to theLib.getResources() based on the actions or events of the user, but also the main list of resources that the application will β€œtransmit” until the user is determined (for example, reading an article) will be determined.

Some of these streaming resources will be the same resources that could be manually called when the user takes action. The script was smart enough not to load the resource twice, keeping track of the loaded.

It also tracks theLib.isLoading . The beginning of this function looked something like this:

 getResources : function(paths, callback) { if (theLib.isLoading) { settimeout(function() { theLib.getResources(paths, callback); }, 100); } theLib.isLoading = true; 

I can no longer do this because I need to return the promise object.

I know I can check theLib.currentDeferred.isResolved() . In this case, if it is not resolved: how to add additional pending objects to the $.when that is being viewed?

+4
source share
1 answer

I think I needed to ask a question in order to find a solution for myself. I basically added the following code to the top of getResources :

if ( ! theLib.currentDeferred.isResolved()) { return $.when(theLib.currentDeferred).always(function() { theLib.getResources(paths); }).promise(); } if ( ! theLib.currentDeferred.isResolved()) { return $.when(theLib.currentDeferred).always(function() { theLib.getResources(paths); }).promise(); } affairs>

The above did not work. The correct solution was to combine the results:

 if ( ! theLib.currentDeferred.isResolved()) { return theLib.currentDeferred.pipe(function() { return theLib.getResources(paths); }); } 
+3
source

All Articles