Despite the many answers here on the topic, I still don't really understand $.Deferred()
objects.
I want to understand them better and avoid any "anti-patterns".
I have read:
https://api.jquery.com/category/deferred-object/
And what "sticks" is that it is an object with methods available to it, such as done()
.
I've tried to create the most simple example possible, based on this answer:
function function1() {
// create a deferred object first
var dfrd1 = $.Deferred();
// mimic an async request
setTimeout(function() {
// lots of async stuff here
// resolve the deferred object
dfrd1.resolve();
}, 1000);
// return a promise()
return dfrd1.promise();
}
function1().done(function() {
// when function1 is done, do something
console.log('function1 is done!');
});
There seem to be four components to this:
- Create a
$.Deferred()
object. resolve()
it after the asynchronous block of code.- Return a
promise()
after the asynchronous block of code. - Call the
done()
method.
The above example seems to work as expected, however when I try to apply this logic to a large function that contains an $.ajax()
request, in order to apply a class to content after it has loaded, the class is not being applied.
I can run the addClass()
code via firebug, so there is nothing wrong with that code.
The pseudo-code for the large function scenario is:
function largeFunction(myVar) {
// create a deferred object first
var dfrd1 = $.Deferred();
// lots of code and an ajax request here
// resolve the object and return a promise
// (this seems naive to hope resolve will
// know when everything above has completed)
dfrd1.resolve();
return dfrd1.promise();
}
// call the done() method from an on click event
$(document).on("click", ".some_class", function() {
largeFunction(myVar).done(function() {
console.log('largeFunction(myVar) is done, you can now add class');
var my_classes = $(".my_class");
$.each(classes, function(index, value) {
$(this).addClass("another_class");
});
});
});
The following is a good, short, simple answer to a $.Deferred()
question, which I understand the logic of, but doesn't seem to be applicable in my scenario (eg I can't just chain the promise()
after a simple fadeOut()
):
https://stackoverflow.com/a/24234881/1063287
Question
In the large function example above, what conventions do I need to follow in order to call done()
after the ajax request etc has finished executing?