2016-05-03 9 views
3

Ich versuche ein mySQL/PHP-Projekt von mir neu zu erstellen (eine "neue Registerkarte" -Stilseite speichert Lesezeichen mit Akzentfarben, Ordnern und einem Kurzwahl-/Fixed-Bereich) in IndexedDB für eine clientseitige Speicherlösung (mit der Hoffnung, sie auf eine Chrome-Erweiterung zu verschieben).Hinzufügen von JS-Objekten zu einem Array mit einer Cursorschleife

Ich mag es zu denken, ich habe ein OK Verständnis von JS, aber ich kann nicht herausfinden, warum das folgende nur ein leeres Array zurückgibt. Von dem, was ich sehen kann, wird das "Antwort" -Array am Anfang der Funktion deklariert und sollte daher durch die untergeordneten Funktionen darin zugänglich sein. Das Festhalten in Konsolenprotokollen weist darauf hin, dass das Array erfolgreich mit den durch die Cursor-Iterationen erstellten Objekten verschoben wird. Wenn der Cursor jedoch beendet ist, bleibt die Antwort leer.

// Specify index and key value OR omit for all 
function getItems(ind,key) { 
var response = []; 
var transaction = db.transaction(["items"],"readonly"); 
var store = transaction.objectStore("items"); 

// If args are omitted - grab all items 
if(!ind | !key) { 
    var cursor = store.openCursor(); 
    cursor.onsuccess = function(e) { 
     var res = e.target.result; 
     if(res) { 
      var r = { 
       "name": res.value['name'], 
       "url": res.value['url'], 
       "folder": res.value['folder'], 
       "colour": res.value['colour'], 
       "dial": res.value['dial'], 
       "order": res.value['order'] 
      }; 
      response.push(r); 
      res.continue(); 
     } 
     return response; 
    } 
} else { 
    // If both args are specified query specified index 
    store = store.index(ind); 
    var range = IDBKeyRange.bound(key, key); 
    store.openCursor(range).onsuccess = function(e) { 
     var res = e.target.result; 
     if(res) { 
      var r = { 
       "name": res.value['name'], 
       "url": res.value['url'], 
       "folder": res.value['folder'], 
       "colour": res.value['colour'], 
       "dial": res.value['dial'], 
       "order": res.value['order'] 
      }; 
      response.push(r); 
      res.continue(); 
     } 
     return response; 
    } 
} 
} 

Bin ich dumm und verpasse hier etwas?

Antwort

2

Wenn Sie schreiben:

Sie einen Wert aus dieser anonymen Ereignisbehandlungsroutine zurückkehrt (die ignoriert wird). Wenn dieser Handler ausgeführt wird, ist der Aufruf an getItems() selbst längst abgeschlossen. Sie können nicht einfach return einen Wert, der durch eine asynchrone Operation wie die Cursor-Iteration erzeugt wird.

Versuchen Sie stattdessen:

function getItems(callback, ind, key) { 
    var response = []; 
    var transaction = db.transaction(["items"],"readonly"); 
    var store = transaction.objectStore("items"); 
    transaction.oncomplete = function() { callback(response); }; 

    ... 
} 

Und nennen Sie es wie:

getItems(function(response) { 
    for (var i = 0; i < response.length; ++i) { 
    console.log(response[i]); 
    } 
} /* ind, key */); 
+0

Ah ich sehe. Ich bin immer noch in einer synchronen Denkweise fest. Ich hatte nicht daran gedacht, dass die OnSuccess-Funktion zu nichts führen würde und wahrscheinlich nachdem die Funktion abgeschlossen war. Während ich diese Methode zu schätzen weiß, gibt es eine sauberere Möglichkeit, meinen IndexedDB-Speicher abzufragen, der wiederverwendbar und variabel ist und idealerweise auf ein Array von Objekten ausgibt. –

+0

Nicht wirklich @DeanKellham, so funktioniert der asynchrone Code. Viele halten dies für einen sauberen Weg. – Josh

+0

Zukünftige Versionen von JavaScript werden asynchrone Unterstützung über async/await-Schlüsselwörter mehr in die Sprache integriert haben, und wir möchten IndexedDB jetzt unterstützen, damit es besser damit spielt. –