同步查询与Web SQL数据库
-
29-09-2019 - |
题
我正在研究与客户端SQLITE数据库交互的JavaScript,通过Newish 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正确地制定这些迭代,相互依存的查询。不知何故,以同步或显然同步的方式实际发生的电话。
非常感谢任何人对这个看似棘手的小问题感到沮丧的人。
Naim
PS这是客户的实施 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);
});
});
}
在此示例的延续中,文件夹具有属性 父母 定义它与其他文件夹有关。和文档一样。以下将为您提供文档的路径(成功):
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);
}
其他提示
您可以使用回调以关闭剩余查询的堆栈。或者,您可以使用递归,将堆栈作为参数传递。