Issues Using Deferred/When in jquery to defer a function
-
21-12-2019 - |
Question
I'm really struggling with using Deferred or When with my jquery script. I've been through a number of articles here and elsewhere (including api.jquery.com) and I think I'm just a bit too beginner to understand exactly how to use these calls.
I'm trying to defer a function from running until a previous function in my script has completed.
I have
function datapoints () {
//My long function here where I define $data
};
of which the outcome is an array named $data. I need that $data variable to be defined going into my next function, so I want to defer it.
I've tried to set up the deferral like this:
var deferred = $.Deferred();
deferred.resolve(datapoints());
deferred.done(function result (){
// My function here where I use $data
}
);
I'd really appreciate some pointers on how to clean this up. I've tried recreating various examples but the result every time is a console error saying that $data is undefined. I know the code works because when I manually put in a setTimeout of a few seconds before running the second function everything works fine but I think deferred is a better solution.
Thanks in advance!
Solution
Try fixing your code like this:
deferred.done(function result (data){
// Do not use global $data, use local 'data' instead
}
);
This will ensure the data you are using is in fact the data returned by datapoints()
.
You should also be aware, that unless datapoints()
is an async function, the code you wrote WILL block the JS thread (i.e. if run in browser - it will block the UI).
Promises/deferreds with synchronous functions is not of much use.
The usual pattern would be something like this:
function datapoints() {
var d = $.Deferred()
asyncCallToCreateDatapoints(function callback(data) {
d.resolve(data)
})
return d;
}
datapoints().done(function result(data) {
/* do stuff with data */
})
OTHER TIPS
Try this code:
function datapoints () {
var deferred = $.Deferred();
/* later, when data is ready, call:
deffered.resolve(data);
*/
return deferred.promise();
}
datapoints().then(function () {
// runs when data is ready
})
Not entierly sure what your problem is, but this jsfiddle is working fine for me.
function datapoints () {
//My long function here where I define $data
return {"datapoint1": 1, "datapoint2": 2};
};
var deferred = $.Deferred();
deferred.resolve(datapoints());
deferred.done(function result (data){
// My function here where I use $data
console.log("data: ", data);
});