Web SQLデータベースへの同期クエリ
-
29-09-2019 - |
質問
私は、newishを介して、クライアント側の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ベースのブラウザではそれの兆候を見ていません。
誰もが私がどのようにかもしれないかについての提案を提供できますか、a。コールバックまたはbを使用して、これらの反復的な相互依存のクエリを適切に定式化します。どういうわけか、実際に同期または明らかに同期する方法で実際に発生するように呼びかけます。
この一見トリッキーな小さな問題に亀裂を取る人には、事前に感謝します。
ナイム
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);
}
他のヒント
残りのクエリのスタックに閉じると、コールバックを使用できます。または、再帰を使用して、スタックをパラメーターとして渡すこともできます。