2012-10-02 80 views
2

我有一个本地的WebSQL数据库,我需要与远程MySQL服务器同步完成。为此,我将流程拆分为多个请求,因此我可以在每个请求之间触发回调以显示进度。如何处理许多异步回调

问题是我有严重的竞争条件,我不认为我可以用回调函数解决,因为插入语句在$ .each()函数(也称为循环)中。

我有遍布数据库接口,此同步的问题。我一直在研究如何在jQuery中使用promises和Deferred,但这似乎并不能解决问题。我只需要让这件事情同步。

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"); 
} 
+1

如果它关于异步,你如何确定“回调(”第一个完成“);?可能发生的事情是,第一次回调完成,因为任何原因 –

+0

@Vury这就是为什么我需要运行的ExecuteSQL作为同步,阻挡功能。上面的代码没有。工作,因为有竞争条件随处可见它是什么,我想有工作 – manutenfruits

+0

如果你有一个依赖第二呼叫需要后完成一个例子,首先你需要执行第二个电话放在了第一位。 – Nope

回答

1

jQuery ajax具有使ajax请求同步的设置。很容易做到

$.ajaxSetup({'async': false}); 

...或者只是使用.ajax与每个请求单独设置这一点。

如果你想请求作为一个整体是异步的,但火命令,你必须建立某种形式的队列:https://gist.github.com/3818056 - 不使用递延API,尽管它也许可以。你会像下面这样使用它:

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"}); 

当然,这也要求客户端继续运行,直到继续运行,直到AJAX队列为空。如果有的话,我会建议做:

$(window).on('beforeunload', function() { 
    if (aq.q.length) { 
     return "Still doing back end processing; please stay on page for a moment"; 
    } 
}); 
+0

谢谢!这解决了ajax调用的问题,但主要问题是SQL查询,也是异步的,并且位于for循环中。 – manutenfruits

+0

作为OP的旁注:虽然'async:false'可以解决这个问题,请注意,这会挂起/冻结您的浏览器,直到通话结束,这可能不是很方便用户。 – Nope

+0

为什么你不应该使用延期的API?这通常用于处理诸如等待多个异步操作来完成的情况。 – oligofren