繁体   English   中英

for循环中的Javascript WebSQL查询。 怎么知道什么时候完成?

[英]Javascript WebSQL query within for loop. How to know when finished?

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

基本上我试图复制一些使用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);
                })
            }
        });
    });
}

我也尝试在i == results.rows.length时调用回调函数,但这并不能确保所有查询都完成。

我猜你们之前有些人遇到过同样的问题,所以任何有关如何解决这个问题的帮助,并确保只在for循环完成时才调用回调函数,我们非常感激。

先感谢您。

通常的方法是使用递归异步回调来处理每个单独的记录而不是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();
    }
})();

这最好通过保持“回调”函数执行次数的计数来完成,并且只有在达到结果集的全部量时才继续。

这是您修改的代码:

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.
                        });
                    });
                }
            }
        });
    });
}

至于我,我发现WebSQL的异步API有点简洁,而且由于WebSQL数据库可能会消失(标准已被删除),我建议大家切换到SequelSphere 它是一个HTML5 / JavaScript关系数据库,适用于所有浏览器和所有平台。 它还将数据存储在localStorage中,为WebSQL带来了所有好处,没有任何麻烦。

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

祝好运!

约翰...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM