在循环中对异步SQLite数据库查询使用jQuery deferred和done
我正在制作一个应用程序,其中插入查询放置在循环中:在循环中对异步SQLite数据库查询使用jQuery deferred和done,jquery,sqlite,asynchronous,promise,Jquery,Sqlite,Asynchronous,Promise,我正在制作一个应用程序,其中插入查询放置在循环中: db.transaction(function(ctx) { ctx.executeSql("DELETE from table", [], function(x,y){ $.each(result, function(i, val) { db.transaction(function(ctx) { ctx.execu
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()循环中的所有插入都完成时,如何运行函数或警报之类的东西。我有一个想法,我可以使用jQuery的deferred/done/promise,但不能将其应用于这个问题
有什么想法吗?我试图找到一个复制品,但令我惊讶的是,我没有找到,所以下面是: 您通常会使用
$.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
});
这应该会让你大致了解如何进行,但就我个人而言,我会在一个较低的层面上作出承诺。请详细说明如何执行此操作。有一个稍微整洁的解决方案可用-使用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(删除)的成功。先生,您是个天才!我已经试着这样做了大约一年,但一直没能做到。谢谢