2012-10-02 373 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