I want to use a recursive function but each function should run after previuse complete. so I write this code:
var service = ['users', 'news'],
lastSync = {
'users' : false,
'news' : false
};
db.transaction(function (tx) {
lastSyncFunc(tx,service,0).then(function(){
console.log(lastSync);
});
});
function lastSyncFunc(tx,service,index){
deferred = $q.defer();
tx.executeSql("SELECT time FROM last_sync WHERE fService = ? ORDER BY id DESC LIMIT 1", [service[index]], function (tx, result) {
if (result.rows.length > 0) {
lastSync[service[index]] = result.rows.item(0).fTime;
}
return ++index<service.length ? lastSyncFunc(tx,service,index) : deferred.resolve();
});
return deferred.promise;
}
now my program return false
for lastSync.users
and lastSync.users
because run this section before function completely run.
Manual multiple async calls handling is not always best decision.
You can try to use $q.all()
for that.
To be simple, second step should be write promisified version for single query:
const pDbExec = (tx, sql, params = []) => {
let deferred = $q.defer();
tx.executeSql(sql, params, (tx, res) => deferred.resolve(res));
return deferred.promise();
}
First step should be "check of existance of promisified version of library/methods I use".
Then, just call $q.all
with map your service list into promises:
const SQL_SvcLastSync = `SELECT time FROM ... LIMIT 1`;
db.transaction(tx => {
$q.all(service.map(svc => pDbExec(tx, SQL_SvcLastSync, [svc])))
.then(results =>
results.map(res =>
res.rows.length > 0 ? res.rows.item(0).fTime : null))
.then(results => console.log(results));
});
To format results as key/value pairs you have two options:
.then(results =>
results.reduce((acc, res, i) => (acc[service[i]]=res, acc), {}))
Simple solution with adding parameter for saving same deferred object between recursive calls:
try something like this:
function lastSyncFunc(tx,service,index, def){
var deferred = def || $q.defer();
tx.executeSql(
"SELECT time FROM last_sync WHERE fService = ? ORDER BY id DESC LIMIT 1",
[service[index]],
function (tx, result) {
if (result.rows.length > 0) {
lastSync[service[index]] = result.rows.item(0).fTime;
}
return ++index<service.length ?
lastSyncFunc(tx,service,index, deferred) :
deferred.resolve();
});
return deferred.promise;
}
I just a provide deferred to maxdepth, where we can to resolve it.