我正在研究一些与客户端 SQLite 数据库交互的 JavaScript,通过新的 window.openDatabase(...)
,database.transaction(.. .)
和相关的 API。大多数人都知道,当您以这种方式执行查询时,它是一个异步调用,这通常很好。您可以使用回调进行调用并根据需要处理结果。
在我目前的情况下,我正在为一个在本地存储的数据库中进行一些层次结构遍历的客户端开发算法。我遇到问题的算法部分需要从某行开始,该行引用了表中另一行的“父级”(按 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 将“未定义”插入其中,然后脚本在尝试检查 rs[0] 的类型时崩溃。
当我尝试使用回调(db.getRSAndCallback(sql, callbackFunc)
,我将其用于较早的非相互依赖的查询时就好了)进行设置时,情况更糟:内部循环像疯了一样起飞,因为 id 没有得到更新;大概是因为循环使 JavaScript 解释器非常忙碌,以至于它实际上从未填充 rs
。在一些人工测试中,我在几次迭代后强制中断内部循环,所有回调都在循环结束后开始全部通过。
http://dev.w3.org/html5/webdatabase/#synchronous-database-api 处的“标准”(例如现在)似乎表明有一个同步 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;
},
.
.
.
最佳答案
我使用回调和闭包来解决类似的问题,请考虑:
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);
});
});
}
在这个例子的延续中,文件夹有一个属性 parent 来定义它与其他文件夹的关系。就像文档一样。以下内容将为您提供使用闭包的文档路径(成功):
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);
}
关于javascript - 对 Web SQL 数据库的同步查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3903155/