Я работаю над небольшим количеством JavaScript, который взаимодействует с клиентской базой данных SQLite через новые window.openDatabase(...)
, database.transaction(...)
и связанные API.Как большинство из вас знает, когда вы выполняете запрос таким образом, это асинхронный вызов, который обычно хорош.Вы можете сделать вызов и обработать результаты соответствующим образом с помощью обратных вызовов.
В моей текущей ситуации я работаю над алгоритмом для клиента, который выполняет некоторую иерархическую прогулку в локальной базе данных.Часть алгоритма, с которой у меня возникают проблемы, требует начала с некоторой строки, которая имеет ссылку на «родителя» (по идентификатору), который находится в другой строке в таблице.Я должен продолжать идти вверх по этому дереву, пока не достигну корня.
Проблема в том, что я не уверен, как использовать запрос асинхронного стиля с обратным вызовом для продолжения подачиидентификаторы родительского цикла.В идеале я мог бы получить запрос для блокировки, чтобы я мог делать все это в цикле.Вот ключевые части моей текущей настройки:
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;
}
}
Как вы можете себе представить, это не работает хорошо.ierarchyArr получает «неопределенное», помещенное в него, и затем скрипт падает, когда он пытается проверить тип 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;
},
.
.
.