Javascript 如何处理许多异步回调的完成

Javascript 如何处理许多异步回调的完成,javascript,jquery,web-sql,Javascript,Jquery,Web Sql,我有一个本地WebSQL数据库,需要与远程MySQL服务器同步。为此,我将流程拆分为多个请求,以便在每个请求之间启动回调以显示进度 问题是这里存在严重的争用条件,我认为回调无法解决,因为insert语句位于$.each()函数(也称为for循环)中 我发现这个异步问题遍布数据库接口。我一直在研究如何在jQuery中使用承诺和延迟,但这似乎并没有解决问题。我只需要让这东西同步 evalua.webdb.sync = function(callback){ $.getJSON("index.php

我有一个本地WebSQL数据库,需要与远程MySQL服务器同步。为此,我将流程拆分为多个请求,以便在每个请求之间启动回调以显示进度

问题是这里存在严重的争用条件,我认为回调无法解决,因为insert语句位于$.each()函数(也称为for循环)中

我发现这个异步问题遍布数据库接口。我一直在研究如何在jQuery中使用承诺和延迟,但这似乎并没有解决问题。我只需要让这东西同步

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

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

$.ajaxSetup({'async': false});
…或者只需使用
.ajax
并在每个请求中单独设置

如果希望请求作为一个整体是异步的,但按顺序发出,则必须创建某种队列:--不使用延迟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";
   }
});

我想我可能在这里找到了一个解决方案:


我仍然需要知道如何做出不同的插入语句,以及如何处理一个接一个的承诺。但这是一组较小的链式回调。

如果是关于异步的,那么如何确定“回调”(“第一个完成”)2.回调可能首先完成,因为reason@Vury这就是为什么我需要将executeSql作为一个同步的阻塞函数运行。上面的代码不起作用,因为到处都有竞争条件。这是一个例子,说明了如果你有一个依赖项,第二次调用需要在第一次调用后完成,我希望它能起作用您需要在第一个调用完成/成功后执行第二个调用。@FrançoisWahl我知道,但我不能简单地在第一个调用中启动回调。getJSON(),因为executeSql也是异步的,所以我永远不知道它什么时候完成。我可以在AJAX请求完成时启动回调,让SQL语句自己完成。但是我有外键,所以这里的竞争条件会杀死它。谢谢!这解决了AJAX调用的问题,但主要的问题是SQL查询,也是异步的OU和for循环内。OP:while
async:false
可能会解决此问题,请注意,这将挂起/冻结浏览器,直到调用完成,这可能对用户不太友好。为什么不使用延迟api?这通常在处理诸如等待多个异步ope之类的情况时非常有效需要完成的口粮。