jquery deferred in .each loop
26,908
Solution 1
You'll need a promise for each iteration
var processSchema = function(data) {
var promises = [];
$.each(table, function() {
var def = new $.Deferred();
db.executeSql(sql, data, function(tx, results){
def.resolve(results);
});
promises.push(def);
});
return $.when.apply(undefined, promises).promise();
}
Solution 2
For Functional Programming fiends (like myself), here's a single-expression version of adeneo's answer:
var processSchema = function(data) {
return $.when.apply($, $.map(table, function() {
var def = new $.Deferred();
db.executeSql(sql, data, function(tx, results){
def.resolve(results);
});
return def;
})).promise();
};
Also I'd like to note that you are iterating over table
, but aren't doing anything with each item in the iteration (i.e. the callback in your each
has no arguments.) Now, I'm not sure what your goal is, but this doesn't seem right to me :P
Related videos on Youtube
Author by
gdex
Updated on December 20, 2020Comments
-
gdex over 3 years
This should be a simple one. I have a function that is called and I need to wait for all the async operations to complete. what I want is something like this...
self.processSchema(data).done(function(results){ //do stuff});
The processSchema function loops using $.each and calls an async method.
var processSchema = function(data) { var def = new $.Deferred(); $.each(table, function() { //calls an async SQLitePlugin method db.executeSql(sql, data, function(tx, results){ def.resolve(results); } } return(def.promise()); }
This does not seem to work, I am new to $.Deferred so any guidance would be helpful
-
Robin Giltner over 10 yearsI think you would need a new deferred for every single db.executeSql, and then do a large $.when(deferred1, deferred2...defferedN).then(function(data1, data2...dataN) { });
-
-
gdex over 10 yearsadeneo, should that return defcon.promise() ?
-
adeneo over 10 yearsYes it should! One could return the array of promises, but to keep the syntax of how the OP want's to call the function, I figure one master promise that is returned and then resolved when all the other promises are resolved would be easier, and then pass all the returned data as the arguments array directly ?
-
gdex over 10 years@Jan Dvorak, so the def.apply will work inside of loop?
-
hawk over 10 years@adeneo actually you can simply return result of
$.when
, without creating "master" promise? -
Tomalak over 10 years@hawk Because you actually want to return a Promise, not a Deferred. Because Promises are read-only.
-
John Dvorak over 10 years@gdex
apply
takes an array and uses it as a list of arguments.$.when
takes a list of promises and returns a promise that resolves when all arguments resolve -
John Dvorak over 10 years@Tomalak
$.when.apply(...).promise()
-
adeneo over 10 years@hawk - indeed you could, as chaining
done
on the function call would be the same as chainingthen
on the$.when
, and as Jan points out, just addingpromise()
returns the promise and would be the same as the master deferred. -
Milosz over 10 yearsFor what it's worth, it would be safer to pass
$
as the context toapply
. We don't know if$.when
usesthis
internally, but if it does we want it pointing to$
, hence$.when.apply($, promises).promise()
. -
gdex over 10 yearsUsing the
apply().then
gives me an argument array of each deferred result which may be helpful in my scenario. The.promise()
only returns the last result which is fine in some cases. I appreciate the help! -
adeneo over 10 years@gdex - that's actually true, then() would return an array of results, which could be useful.
-
gdex over 10 yearsThere is a lot more to the function then I posted, for brevity I did not include some of the non essential stuff...