Javascript Web-SQL数据库的同步查询
我正在开发一种JavaScript,它通过新的Javascript Web-SQL数据库的同步查询,javascript,sqlite,synchronization,web-sql,Javascript,Sqlite,Synchronization,Web Sql,我正在开发一种JavaScript,它通过新的窗口.openDatabase(…),数据库.transaction(…)和相关API与客户端SQLite数据库交互。大多数人都知道,当以这种方式执行查询时,它是一个异步调用,这通常是好的。您可以通过回调进行调用,并根据需要处理结果 在我目前的情况下,我正在为一个客户端开发一个algo,该客户端在本地存储的数据库中执行一些层次结构遍历。我遇到问题的算法部分需要从某一行开始,该行引用了“父级”(按id),这是表中更高的另一行。我得一直走到这棵树的根部
窗口.openDatabase(…)
,数据库.transaction(…)
和相关API与客户端SQLite数据库交互。大多数人都知道,当以这种方式执行查询时,它是一个异步调用,这通常是好的。您可以通过回调进行调用,并根据需要处理结果
在我目前的情况下,我正在为一个客户端开发一个algo,该客户端在本地存储的数据库中执行一些层次结构遍历。我遇到问题的算法部分需要从某一行开始,该行引用了“父级”(按id),这是表中更高的另一行。我得一直走到这棵树的根部
问题是,我不确定如何使用带有回调的异步样式查询来继续向循环父ID提供反馈。理想情况下,我可以阻止查询,以便在循环中完成所有操作。以下是我当前设置的关键部分:
for (i in search.searchResults.resultsArray)
{
hierarchyArr = new Array();
pageHierarchyArr = new Array();
id = search.searchResults.resultsArray[i].ID;
while (id != null && id != "")
{
var hierarchySql = "SELECT ID, parentID, type, content FROM content WHERE ID = " + id;
// This is a prettied up call to database.transaction(...)
var rs = db.getRS(hierarchySql);
// Ideally the code below doesn't execute until rs is populated
hierarchyArr.push(rs[0]);
if (rs[0].type == "page")
{
pageHierarchyArr.push(rs[0]);
// Do some additional work
}
id = rs[0].parentID;
}
}
正如你可能想象的那样,它不起作用。hierarchyArr得到一个“undefined”推送到其中,然后当脚本试图检查rs[0]的类型时崩溃
当我尝试用回调设置它时(db.getRSAndCallback(sql,callbackFunc)
,我在前面的非相互依赖的查询中使用了它,这很好),情况更糟:内部循环像疯了一样启动,因为id没有得到更新;大概是因为循环让JavaScript解释器一直很忙,以至于它从来没有实际填充过rs
。在一些人工测试中,我强制内部循环在几次迭代后中断,所有回调都在循环结束后开始执行
at的“标准”(比如现在的标准)似乎表明存在一个同步API,但我还没有在任何基于WebKit的浏览器上看到它的任何迹象
有谁能给我一些建议吗。使用回调或b正确地表达这些迭代的、相互依赖的查询。以某种方式使调用以同步或明显同步的方式实际发生
非常感谢任何人在这个看似棘手的小问题上尝试一下
奈姆
另外,以下是客户对db.getRS
的实现,以供参考:
.
.
.
getRS: function(sql)
{
var output = [];
db.database.transaction(function(tx)
{
tx.executeSql(sql, [], function(tx,rs)
{
for(i = 0; i < rs.rows.length; i++)
{
output.push(rs.rows.item(i));
}
},
function(tx, error) { ... }
)});
return output;
},
.
.
.
。
.
.
getRS:函数(sql)
{
var输出=[];
数据库事务(函数(tx)
{
tx.executeSql(sql,[],函数(tx,rs)
{
对于(i=0;i
您可以使用回调来关闭剩余查询的堆栈。或者可以使用递归,将堆栈作为参数传递。我使用回调和闭包来解决类似的问题,请考虑:
function getFolder(id, callback) {
var data = [];
ldb.transaction(function (tx) {
tx.executeSql('SELECT * FROM folders where id=?',
[id],
function (tx, results) {
if (results.rows && results.rows.length) {
for (i = 0; i < results.rows.length; i++) {
data.push(results.rows.item(i));
}
}
if (typeof(callback) == 'function')
callback(data);
},
function (tx, error) {
console.log(error);
});
});
}
哦,我还想提一下:如果我在调试脚本,并且在
hierarchyArr.push(rs[0])上设置了一个断点代码>脚本工作正常。通过它,记录集被填充,id被更新,它遍历层次结构。禁用断点并让它运行,它就会在我上面提到的地方崩溃,毫无疑问,因为当前执行的暂停可以让它完成查询。我认为在这种情况下,递归可能是一种可行的方法,但我想坚持其他想法。幸运的是,我对完整数据集的处理在记录之间不是相互依赖的,因此不会太混乱。这正是我最终实现它的方式。谢谢你花时间把你的代码放在这里给别人看!我忘了做那件事很抱歉,请您解释一下,将data[]变量放在外部作用域中与放在回调函数中是否有任何区别?
function getDocPath(doc, callback) {
var path = [];
var parent = doc.parent;
var success = function(folder) {
var folder = folder[0];
parent = folder.parent;
path.push({'id':folder.id,'name':folder.name});
if (parent != "undefined")
getFolder(parent, success);
else
if ( typeof(callback) == 'function' ) callback(path.reverse());
}
getFolder(parent, success);
}