2014-11-06 19 views
1

我在做一個應用程序,其中插入查詢被放置在一個循環內:使用jQuery推遲和環型異步SQLite數據庫查詢做

db.transaction(function(ctx) { 
    ctx.executeSql("DELETE from table", [], function(x,y){ 
     $.each(result, function(i, val) {      
      db.transaction(function(ctx) { 
       ctx.executeSql("INSERT INTO table(value1, value2) VALUES('"+val.value1+"','"+val.value2+"')", []); 
      }, function(err){ 
       alert("Error processing SQL: "+err.message); 
      },function(){ 
       console.log("finished one loop of insert"); 
      }); 
     });  
    }); 

}, function(){ 
    //error 
}, function(){ 
    //success 
    console.log("finished syncing"); 
    //this runs before all the inserts as the inserts are seperate queries 
}); 

但我似乎無法弄清楚如何運行的函數或當$ .each()循環中的所有INSERTS都完成時發出警報或某事。我有一個想法,我可以使用jQuery的延遲/完成/承諾,但不能將其應用於此問題。

任何想法?

回答

2

我試圖找到一個副本,並讓我驚訝我沒有,所以這裏有雲:

你會一般採用$.when爲了聚合多個承諾,如果它是你可以使用$.when.apply一個動態的數字,其需要一個數組。一般 - 這看起來是這樣的:

var promises = [p1, p2, p3, ...]; 
$.when.apply($, promises).then(function(){ 
     // all done, 
     arguments; // contains all the results in an array-like 
}); 

在您的例子 - 這應該是這樣的:

var promises = []; 
var transactionDone = $.Deferred(); // represent the transaction 
promises.push(transactionDone); 
db.transaction(function(ctx) { 
    ctx.executeSql("DELETE from table", [], function(x,y){ 
     $.each(result, function(i, val) { 
      var d = $.Deferred(); 
      db.transaction(function(ctx) { 
       ctx.executeSql("INSERT INTO table(value1, value2) VALUES('"+val.value1+"','"+val.value2+"')", []); 
      }, d.reject, d.resolve); // resolve/reject when done/fail 
      promises.push(d); // keep track of it. 
     }); 
    }); 
}, transactionDone.reject, transactionDone.resolve); 


$.when.apply($, promises).then(function(){ 
     // transaction itself is done and all inserts are complete 
}); 

這應該給你如何進行一個大致的瞭解,但我個人倒在promisify低等級。請在refer to this answer上詳細瞭解如何操作。

+0

先生,你是個天才!我一直在嘗試這樣做大約一年,從來沒有能夠。謝謝!! – JamesG 2014-11-06 12:19:14

1

稍微更整潔的解決方案是可用的 - 通過使用jQuery的$.Deferred(function(dfrd) {...})表單 - 兩次 - 一個外部和一個(循環)內部 - 並通過選擇稍微不同的實現策略來避免外部變量。

$.Deferred(function(outerDfrd) { 
    db.transaction(function(ctx) { 
     ctx.executeSql("DELETE from table", [], function(x,y) { 
      var promises = $.map(result, function(val) { 
       return $.Deferred(function(innerDfrd) { 
        db.transaction(function(ctx) { 
         ctx.executeSql("INSERT INTO table(value1, value2) VALUES('" + val.value1 + "','" + val.value2 + "')", []); 
        }, innerDfrd.reject, innerDfrd.resolve); 
       }).promise(); 
      }); 
      $.when.apply(null, promises).then(outerDfrd.resolve, outerDfrd.reject); 
     }); 
    }, outerDfrd.reject, outerDfrd.notify); 
}).progress(function() { 
    //outer db.transaction has successfully completed 
}).fail(function(err) { 
    //report/handle error here 
}).done(function() { 
    //overall success here 
}); 

與其他答案的區別是微妙的。將創建完全相同數量的遞延數據,但總體實現機制不同,因爲外部遞延數據已解決,以響應已解決的所有內部數據。這裏的$.when.apply(...)僅限於內部遞延,不包括外部,並且鏈接使內部成功(或失敗)的最終連接回到外部。

交易時,您有機會記錄/報告中間進度 - 成功執行外部db.transaction(DELETE)。