Frage

Ich bin auf einem wenig JavaScript arbeiten, dass wirkt mit einer clientseitigen SQLite-Datenbank, über die newish window.openDatabase(...), database.transaction(...) und verwandte APIs. Wie die meisten von euch wissen, wenn Sie eine Abfrage auf diese Weise auszuführen ist es ein asynchroner Aufruf, die in der Regel gut. Sie können den Anruf tätigen und die Ergebnisse gegebenenfalls mit Rückrufen behandeln.

In meiner jetzigen Situation arbeite ich an einem algo für einen Kunden, der in der lokal gespeicherten Datenbank eine Hierarchie zu Fuß tut. Der Teil der Algo Ich habe Probleme mit irgend erfordert Zeile beginnend, die einen Verweis auf eine „Eltern“ hat (durch id), die eine andere Reihe weiter oben in der Tabelle ist. Ich habe zu halten, diesen Baum zu Fuß, bis ich die Wurzel erreichen.

Das Problem ist, dass ich an einem Punkt bin, wo ich bin nicht sicher, wie eine asynchrone Art Abfrage mit einem Rückruf zu verwenden, halten Sie die Schleife Eltern ids Fütterung. Im Idealfall könnte ich die Abfrage erhalten so zu blockieren, dass ich sie alle in der Schleife tun. Hier die wichtigsten Teile meiner aktuellen Setup:

    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;
        }
    }

Wie Sie sich vorstellen können, ist es nicht gut funktionieren. hierarchyArr bekommt eine „undefined“ hinein geschoben, und dann das Skript stürzt ab, wenn es versucht, die Art von rs zu überprüfen [0].

Wenn ich versuche, es mit einem Rückruf einzurichten (db.getRSAndCallback(sql, callbackFunc), die ich für die früher verwenden, nicht voneinander abhängig Abfragen ganz gut), ist es noch schlimmer: die innere Schleife wie verrückt nimmt ab, weil id ist nicht immer aktualisiert; vermutlich, weil die Schleife des JavaScript-Interpreter hält so beschäftigt, dass sie eigentlich nie rs füllt. In einigen künstlichen Test, wo ich die innere Schleife nach einigen Iterationen zu brechen gezwungen alle Rückrufe am Ende kommen durch alle gestartet, nachdem die Schleife beendet.

Der "Standard" (wie es jetzt ist) unter http : //dev.w3.org/html5/webdatabase/#synchronous-database-api scheint, um anzuzeigen, dass ein synchrones API ist, aber ich habe ein Zeichen von ihm nicht auf irgendwelchen WebKit-basierten Browsern gesehen <. / p>

Kann jemand bieten Anregungen, wie ich könnte entweder ein. richtig formuliert diese iterativen, voneinander abhängigen Abfragen Rückrufe oder b verwendet wird. irgendwie den Anruf bekommen, um tatsächlich in einem synchronen oder scheinbar synchron passieren.

Vielen Dank im Voraus für jeden, der an diesem scheinbar heikel kleinen Problem einen Riss nimmt.

Naim

P. S. Hier ist die Client-Implementierung von db.getRS Referenz:

.
.
.
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;
},
.
.
.
War es hilfreich?

Lösung

Ich benutzte Rückrufe und einen Verschluss ein ähnliches Problem zu lösen, sollten Sie:

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 der Fortsetzung dieses Beispiels hat Ordner eine Eigenschaft Eltern es die Beziehung zu anderen Ordner zu definieren. Wie funktioniert ein Dokument. Im Folgenden erhalten Sie den Pfad eines Dokuments mit einem Verschluss ( Erfolg ):

  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);
  }

Andere Tipps

Sie können Rückrufe mit einem Verschluss zu Ihrem Stapel verbleibenden Abfragen verwenden. Oder Sie könnten Rekursion, vorbei an den Stapel als Parameter verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top