我想我有一个相对简单的问题,但我一直在思考,甚至谷歌也没有给我一个我可以使用的答案。
基本上我试图复制一些使用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循环完成时才调用回调函数,我们非常感激。
提前谢谢。
答案 0 :(得分:8)
通常的方法是使用递归异步回调来处理每个单独的记录,而不是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();
}
})();
答案 1 :(得分:2)
最好通过保持“回调”函数执行次数的计数来完成,并且只有在达到结果集的全部数量后才进行。
以下是您的代码修改:
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数据库可能会消失(标准已被删除),我建议大家切换到{{3} }。它是一个HTML5 / JavaScript关系数据库,适用于所有浏览器和所有平台。它还将数据存储在localStorage中,为WebSQL带来了所有好处,而且没有任何麻烦。
如果上述解决方案不适合您,请告诉我。
祝你好运!...约翰