使用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的延迟/完成/承诺,但不能将它应用于这个问题。

有任何想法吗?

我试图找到一个副本,令我惊讶的是我没有,所以这里是:

你通常使用$.when来聚合多个promises,如果它是一个动态数字你可以使用$.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 }); 

这应该让你大致了解如何继续,但我个人会在较低的层面上宣传。 有关如何操作的更多详细信息,请参阅此答案 。

一个稍微整洁的解决方案是可用的 – 通过使用jQuery的$.Deferred(function(dfrd) {...})forms避免外部变量 – 两次 – 一个外部和一个(循环)内部 – 并通过选择稍微不同的履行策略。

 $.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(...)仅限于内部Deferreds,不包括外部,并且链接.then()使得从内部成功(或失败)的最终连接回到外部。

在讨价还价中,您将有机会记录/报告中间进度 – 外部db.transaction(DELETE)的成功。