for循环中的Javascript-WebSQL查询。如何知道何时完成?

for循环中的Javascript-WebSQL查询。如何知道何时完成?,javascript,for-loop,web-sql,Javascript,For Loop,Web Sql,我想我有一个相对简单的问题,但我一直在循环思考,甚至谷歌也没有给我一个我可以使用的答案 基本上,我试图复制一些使用WebSQL存储在本地的记录。复制不是问题,但我需要知道所有复制操作何时完成,然后我的程序才能继续 WebSQL调用是非同步的,所以我通常做这些事情的唯一方法是使用回调函数。但是,因为查询是在for循环中完成的,所以我不能使用回调函数,因为它将在第一个完成的查询中启动,如代码所示 代码如下: function copyRecords(old_parent_id, new_parent

我想我有一个相对简单的问题,但我一直在循环思考,甚至谷歌也没有给我一个我可以使用的答案

基本上,我试图复制一些使用WebSQL存储在本地的记录。复制不是问题,但我需要知道所有复制操作何时完成,然后我的程序才能继续

WebSQL调用是非同步的,所以我通常做这些事情的唯一方法是使用回调函数。但是,因为查询是在for循环中完成的,所以我不能使用回调函数,因为它将在第一个完成的查询中启动,如代码所示

代码如下:

function copyRecords(old_parent_id, new_parent_id, callback){
    var db = openDatabase('test', '1.0', 'test', 50 * 1024 * 1024);
    db.transaction(function (tx) {
        tx.executeSql('SELECT * FROM table WHERE parent_id = ?', [old_parent_id], function(tx, results){
            for(var i = 0; i < results.rows.length; i++){
                db.transaction(function (tx2) {
                    tx2.executeSql('INSERT INTO table (name, parent_id) VALUES (?, ?)', [results.rows.item(i).name, new_parent_id], callback);
                })
            }
        });
    });
}
函数copyRecords(旧的\u父\u id、新的\u父\u id、回调){
var db=openDatabase('test','1.0','test',50*1024*1024);
数据库事务(功能(tx){
tx.executeSql('SELECT*FROM table WHERE parent_id=?',[old_parent_id],function(tx,results){
对于(var i=0;i
我还尝试在
I==results.rows.length
时调用回调函数,但这并不意味着所有查询都已完成

我想你们中的一些人以前也遇到过同样的问题,因此,对于如何解决这个问题并确保只在for循环完成时调用回调函数的任何帮助都是非常感谢的


提前感谢。

这最好通过记录“回调”函数的执行次数来完成,并且只有在达到结果集的全部数量后才能继续

以下是经过修改的代码:

function copyRecords(old_parent_id, new_parent_id, callback){
    var db = openDatabase('test', '1.0', 'test', 50 * 1024 * 1024);
    db.transaction(function (tx) {
        tx.executeSql('SELECT * FROM table WHERE parent_id = ?', [old_parent_id], function(tx, results){
            if (results.rows.length == 0) 
                callback(); // don't forget this case!
            else {
                var nbrInserted = 0; // This will keep track of how many have been inserted
                for(var i = 0; i < results.rows.length; i++){
                    db.transaction(function (tx2) {
                        tx2.executeSql('INSERT INTO table (name, parent_id) VALUES (?, ?)', [results.rows.item(i).name, new_parent_id], function() {
                            ++nbrInserted; // increment this for every insert
                            if (nbrInserted == results.rows.length) // check if complete
                                callback(); // Do your callback.
                        });
                    });
                }
            }
        });
    });
}
函数copyRecords(旧的\u父\u id、新的\u父\u id、回调){
var db=openDatabase('test','1.0','test',50*1024*1024);
数据库事务(功能(tx){
tx.executeSql('SELECT*FROM table WHERE parent_id=?',[old_parent_id],function(tx,results){
if(results.rows.length==0)
callback();//别忘了这个例子!
否则{
var nbristed=0;//这将跟踪插入的数量
对于(var i=0;i
至于我,我发现WebSQL的异步API有点混乱,而且由于WebSQL数据库可能会消失(该标准已被放弃),我建议大家都切换到。它是一个HTML5/JavaScript关系数据库,可以跨所有浏览器和所有平台工作。它还将数据存储在localStorage中,使其具有WebSQL的所有优点,而无需任何麻烦

如果上述解决方案不适用于您,请告诉我

祝你好运


john…

通常的方法是使用递归异步回调来处理每个记录,而不是使用
for
循环

虽然还有更多记录,但异步回调会调用自身。当没有记录时,它可以调用您提供的回调

下面的代码将替换内部回调处理程序的内容:

(function nextRecord() {
    var row = results.rows.shift();
    if (row) {
        db.transaction(function (tx2) {
            tx2.executeSql('INSERT INTO table (name, parent_id) VALUES (?, ?)',
                [row.item(i).name, new_parent_id], nextRecord);
       });
    } else {
        callback();
    }
})();

通过结果将内部交易移出循环,从而使插入循环完全进入交易内部,这是否可行?您真的应该声明您对SequelsSphere的兴趣。这一点很好。你完全正确。请原谅。。。我连接到SequelSphere,忍不住插上了插头。异步回调并不麻烦-请参阅我的答案,了解如何正确地执行此操作!p、 p.s.async非常麻烦,而且非常必要。只是我的意见。我非常喜欢你的答案,但是如果我读对了,当select.Doh!没有返回任何行时,你的答案就会出错。。。触摸。。。已经修好了。谢谢你的回答!我从未想过使用递归函数!感谢您的想法,但是web sql结果似乎不支持shift()函数,因为它不是数组。所以我不得不手动增加一个计数器,它成功了!