javascript 同步查询到 Web SQL 数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3903155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Synchronous query to Web SQL Database
提问by Naim
I'm working on a bit of JavaScript that interacts with a client-side SQLite database, via the newish window.openDatabase(...), database.transaction(...)and related APIs. As most of you know when you execute a query in this way it is an asynchronous call, which is typically good. You can make the call and handle the results as appropriate with callbacks.
我工作的一个JavaScript代码的是通过新望与客户端的SQLite数据库进行交互,window.openDatabase(...),database.transaction(...)和相关的API。大多数人都知道,当您以这种方式执行查询时,它是一个异步调用,这通常是好的。您可以使用回调进行调用并根据需要处理结果。
In my current situation I'm working on an algo for a client that does some hierarchy walking in the locally stored database. The part of the algo I'm having trouble with requires starting at some row, which has a reference to a "parent" (by id) that is another row further up in the table. I have to keep walking up this tree until I reach the root.
在我目前的情况下,我正在为客户端开发一种算法,该算法在本地存储的数据库中执行一些层次结构。我遇到问题的算法部分需要从某行开始,该行引用了“父”(按 id),该“父”是表中的另一行。我必须继续沿着这棵树向上走,直到到达根部。
The problem is that I'm at a point where I'm not sure how to use an asynchronous style query with a callback to keep feeding the loop parent ids. Ideally I could get the query to block so that I can do it all in the loop. Here's the key parts of my current setup:
问题是我现在不确定如何使用带有回调的异步样式查询来继续提供循环父 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;
}
}
As you might imagine, it doesn't work well. hierarchyArr gets an "undefined" pushed into it, and then the script crashes when it tries to check the type of rs[0].
正如您想象的那样,它的效果不佳。hierarchyArr 将“未定义”推入其中,然后脚本在尝试检查 rs[0] 的类型时崩溃。
When I try to set it up with a callback (db.getRSAndCallback(sql, callbackFunc), which I used for the earlier, non-interdependent queries just fine) it's worse: the inner loop takes off like crazy because id isn't getting updated; presumably because the loop is keeping the JavaScript interpreter so busy that it never actually fills rs. In some artificial testing where I forced the inner loop to break after a few iterations all the callbacks started coming through all at the end, after the loop finished.
当我尝试使用回调设置它时(db.getRSAndCallback(sql, callbackFunc)我用于早期的非相互依赖查询就好了),情况更糟:内部循环像疯了一样起飞,因为 id 没有得到更新;大概是因为循环使 JavaScript 解释器如此忙碌以至于它从未真正填充rs. 在一些人工测试中,我强制内部循环在几次迭代后中断,所有回调在循环结束后开始全部结束。
The "standard" (such as it is right now) at http://dev.w3.org/html5/webdatabase/#synchronous-database-apiseems to indicate that there is a synchronous API, but I haven't seen any sign of it on any WebKit based browsers.
http://dev.w3.org/html5/webdatabase/#synchronous-database-api 上的“标准”(例如现在)似乎表明有一个同步 API,但我没有看到任何在任何基于 WebKit 的浏览器上标记它。
Can anyone offer suggestions on how I might either, a. properly formulate these iterative, interdependent queries using callbacks or, b. somehow get the call to actually happen in a synchronous or apparently synchronous manner.
任何人都可以就我如何提供建议,a。使用回调或 b. 正确地制定这些迭代的、相互依赖的查询。以某种方式使调用以同步或明显同步的方式实际发生。
Many thanks in advance for anyone who takes a crack at this seemingly tricky little problem.
非常感谢任何破解这个看似棘手的小问题的人。
Naim
奈姆
P.S. Here's the client's implementation of db.getRSfor reference:
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;
},
.
.
.
采纳答案by asbjornenge
I used callbacks and a closure to solve a similar problem, consider:
我使用回调和闭包来解决类似的问题,请考虑:
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);
});
});
}
In the continuation of this example, folder has a property parentto define it's relation to other folders. As does a document. The following will get you the path of a document using a closure (success):
在这个例子的延续中,文件夹有一个属性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);
}
回答by danlash
You could use callbacks with a closure to your stack of remaining queries. Or you could use recursion, passing the stack as parameters.
您可以使用回调与剩余查询堆栈的闭包。或者您可以使用递归,将堆栈作为参数传递。

