Mixing sync and async javascript/jquery and getting a success function at the end

- 1 answer

Ad

Wondering what the best solution to this problem is, also this is not my actual code structure or names but the simplest way to illustrate the problem. I have a function which was purely used to perform an ajax call and load a template with jquery.

function load(template) {
    $('#container').load(template, data, function() {
       // complete code here
    }); 
}

Focusing on the 3rd param in $.load(), namely a callback function that runs when the request is complete.

Now I have my load() function in another wrapper function:

function processTask(variable) {
    load(variable);
}

The problem I have is I need some code to run after the ajax load is complete, however as my app has grown my wrapper function processTask may or may not invoke an ajax load so I can't perform my must needed code inside the complete callback.

Do I change my $.load() to perform synchronous or just manage my code better so that if I am calling a $.load() it puts my needed code in the callback and if not it places it where I need it to be?

I have read about javascript Promises and I'm unsure if they will help in this situation.

EDIT

So my processTask is an object method.

function classObj(name, fn) {
    this.name = name;
    this.processTask = fn;
    this.load = function(template) {
        $('#container').load(template, data, function() {
           // complete code here
        });
    }
}

And in context I do this:

var task = new classObj('taskName', function() {  
    this.load('myFile.php'); 
    // Or another function and not load() based on whats needed in the task. 
});

Basically I have an object that I can add custom methods to at will and they can easily be called dynamically, until now they have always loaded a file.

Ad

Answer

Ad

First, change your load function to return the xhr from get (or ajax):

function load(template) {
    return $.get('myFile.php', data, function(result) {
       $('#container').html(result);
    }); 
}

Then, within your code you can use whenthen to perform your code after the load completes if applicable:

var xhr;

/* ... */

if(something){
     xhr = load(template);
}

/* ... */

if(xhr){
    $.when(xhr).then(doSomething);
} else {
    doSomething();
}

And in fact, this can be simplified using the fact that a non-deferred object passed to when (including undefined apparently) will execute the then immediately and get rid of the if:

$.when(xhr).then(doSomething);

If xhr is undefined then when will resolve immediately causing then to execute immediately.

Ad
source: stackoverflow.com
Ad