Reputation: 1577
I have a local WebSQL db that I need to sync with a remote MySQL server. To do so, I have split the process into multiple requests, so I can fire the callback in between every request to show the progress.
The problem is that I have serious race conditions here that I don't think I can solve with the callbacks, because the insert statements are within a $.each() function (aka for loop).
I have this asynchronous problem spread all over the database interface. I have been investigating how to use promises and Deferred in jQuery, but that doesn't seem to solve the problem. I just need to make this thing synchronous.
evalua.webdb.sync = function(callback){
$.getJSON("index.php/get/sync_riesgo",function(data){
evalua.webdb.db.transaction(function(tx){
$(data.riesgos).each(function(index, value){
tx.executeSql('INSERT INTO riesgos (idRiesgo, nombre) VALUES ("'+value.idRiesgo+'", "'+value.nombre+'")');
});
$(data.estancias).each(function(index, value){
tx.executeSql('INSERT INTO estancias (idEstancia, nombre, dimensionMinima) VALUES ("'+value.idEstancia+'", "'+value.nombre+'", "'+value.dimensionMinima+'")');
});
$(data.riesgosestancias).each(function(index, value){
tx.executeSql('INSERT INTO riesgosestancias (idRiesgoEstancia, idRiesgo, idEstancia, porcentaje, indispensable) VALUES ("'+value.idRiesgoEstancia+'", "'+value.idRiesgo+'", "'+value.idEstancia+'", "'+value.porcentaje+'", "'+value.indispensable+'")');
});
});
});
callback("First one done");
$.getJSON("index.php/get/sync_operaciones",function(data){
evalua.webdb.db.transaction(function(tx){
$(data.companhias).each(function(index, value){
tx.executeSql('INSERT INTO companhias (idCompanhia, nombre) VALUES ("'+value.idCompanhia+'", "'+value.nombre+'")');
});
$(data.operaciones).each(function(index, value){
tx.executeSql('INSERT INTO operaciones (idOperacion, nombre, descripcion) VALUES ("'+value.idOperacion+'", "'+value.nombre+'", "'+value.descripcion+'")');
});
});
});
callback("Second one done");
}
Upvotes: 2
Views: 1790
Reputation: 1577
I think I may have found a solution right here:
HTML5 WebSQL: how to know when a db transaction finishes?
I still need to know how to make different INSERT statements, and to handle the promises one after another. But that's a smaller set of chained callbacks.
Upvotes: 0
Reputation: 191779
jQuery ajax has a setting to make ajax requests synchronous. Very easy to do
$.ajaxSetup({'async': false});
...or just use .ajax
and set this individually with each request.
If you want the requests as a whole to be asynchronous but fire in order, you have to create a queue of some kind: https://gist.github.com/3818056 -- doesn't use the Deferred API, though it probably could. You would use it as follows:
var aq = new AjaxQueue();
aq.push({'type': 'get', 'dataType': 'json', 'url': 'index.php/get/sync_riesgo',
'success': "you're really long function"});
aq.push({'type': 'get', 'dataType': 'json', 'url': 'index.php/get/sync_operaciones',
'success': "you're really long function"});
Of course, this also requires the client to continue running until the continue running until the ajax queue is empty. If available, I would suggest doing:
$(window).on('beforeunload', function () {
if (aq.q.length) {
return "Still doing back end processing; please stay on page for a moment";
}
});
Upvotes: 1