5

Daten werden geladen und in der indexeddb-Datenbank gespeichert. Periodisch habe ich die Datenbank abstürzen und den Zugriff darauf verloren. Geben Sie mir bitte eine Lösung, wie indexeddb asynchron verwenden!Wie mit IndexedDB asynchron arbeiten?

Beispielcode, die ich verwende jetzt:

var dataTotal = 0; 
var threads = 6; 

//openIndexeddbConnection(); 

function start(total){ 

dataTotal = total; 
    for (var i = 0; i < threads; i++) { 
    loadData(i); 
    } 
} 

function loadData(dataNum){ 
    var dataNext = dataNum + threads; 
    if(dataNext > dataTotal){ 
    //checkEnd(); 
    return; 
    } 

    $.ajax({ 
    url: baseUrl, 
    data: {offset: dataNum}, 
    success: function (data) { 
     successData(dataNext, data); 
    }, 
    type: 'GET' 
    }); 
} 

function successData(dataNext, data){ 
    var dataArray = data.split(';'); 

    saveData(dataArray); 

    loadData(dataNext); 
} 

function saveData(dataArray){ 

    putItem(); 
    function putItem(i) { 
    var count = i || 0; 
    if(dataArray.length <= i){ 
     return; 
    } 

    var transaction = Indexeddb.transaction([dataTableName], "readwrite"); 
    transaction.onsuccess = function (event) { 
     //continue 
     putItem(count); 
    }; 
    var objectStore = transaction.objectStore(dataTableName); 

    var request = objectStore.add({data: dataArray[count++]}); 
    } 
} 

Antwort

3

Sie verspricht verwenden können, um Daten asynchron zu IndexedDB zu laden und zu speichern. Hier sind zwei Beispielfunktionen zum Laden und Speichern von Daten in einem einfachen Objektspeicher in indexedDB.

Asynchronous Laden von IndexedDB:

function loadFromIndexedDB(storeName, id){ 
 
    return new Promise(
 
    function(resolve, reject) { 
 
     var dbRequest = indexedDB.open(storeName); 
 

 
     dbRequest.onerror = function(event) { 
 
     reject(Error("Error text")); 
 
     }; 
 

 
     dbRequest.onupgradeneeded = function(event) { 
 
     // Objectstore does not exist. Nothing to load 
 
     event.target.transaction.abort(); 
 
     reject(Error('Not found')); 
 
     }; 
 

 
     dbRequest.onsuccess = function(event) { 
 
     var database  = event.target.result; 
 
     var transaction = database.transaction([storeName]); 
 
     var objectStore = transaction.objectStore(storeName); 
 
     var objectRequest = objectStore.get(id); 
 

 
     objectRequest.onerror = function(event) { 
 
      reject(Error('Error text')); 
 
     }; 
 

 
     objectRequest.onsuccess = function(event) { 
 
      if (objectRequest.result) resolve(objectRequest.result); 
 
      else reject(Error('object not found')); 
 
     }; 
 
     }; 
 
    } 
 
); 
 
}

Asynchronous zu IndexedDB Sparend:

function saveToIndexedDB(storeName, object){ 
 
    return new Promise(
 
    function(resolve, reject) { 
 
     if (object.id === undefined) reject(Error('object has no id.')); 
 
     var dbRequest = indexedDB.open(storeName); 
 

 
     dbRequest.onerror = function(event) { 
 
     reject(Error("IndexedDB database error")); 
 
     }; 
 

 
     dbRequest.onupgradeneeded = function(event) { 
 
     var database = event.target.result; 
 
     var objectStore = database.createObjectStore(storeName, {keyPath: "id"}); 
 
     }; 
 

 
     dbRequest.onsuccess = function(event) { 
 
     var database  = event.target.result; 
 
     var transaction = database.transaction([storeName], 'readwrite'); 
 
     var objectStore = transaction.objectStore(storeName); 
 
     var objectRequest = objectStore.put(object); // Overwrite if exists 
 

 
     objectRequest.onerror = function(event) { 
 
      reject(Error('Error text')); 
 
     }; 
 

 
     objectRequest.onsuccess = function(event) { 
 
      resolve('Data saved OK'); 
 
     }; 
 
     }; 
 
    } 
 
); 
 
}

Beispiel Verwendungscode

var data = {'id' : 1, 'name' : 'bla'}; 
 

 
saveToIndexedDB('objectstoreName', data).then(function (response) { 
 
    alert('data saved'); 
 
}).catch(function (error) { 
 
    alert(error.message); 
 
}); 
 

 
// Load some data 
 
var id = 1; 
 
loadFromIndexedDB('objectstoreName', id).then(function (reponse) { 
 
    data = reponse; 
 
    alert('data loaded OK'); 
 
}).catch(function (error) { 
 
    alert(error.message); 
 
});

+0

Danke für die Antwort. hatte ich in der Zukunft geplant, saubere Promise oder Rxjs zu verwenden. Mit Promise komfortablere Fangfehler. Aber ich möchte Code ohne Fehler machen. Im Beispiel öffnen Sie jedes Mal eine neue indxedDBbut Verbindung, aber ich benutze nur eine einzige. Ich denke, wir sollten so etwas wie Concurrency Pattern verwenden: Produzent und Verbraucher – Greg

2

Ich habe idb verwendet - eine einfache Bibliothek, die IndexedDB mit Versprechen verpackt. Diese machen asynchrone DB-Aktionen viel einfacher zu bedienen.

Wenn Sie Targeting Chrome (oder eine Transpiler verwenden, die sie unterstützt) Sie async und await verwenden können, um Ihren Code zu vereinfachen:

async function saveData(dataArray) { 
    const db = await idb.open('YourDB', currentVersion, upgradeFunction); 
    const tran = await db.transaction('StoreName', 'readwrite'); 
    const store = tran.objectStore('StoreName'); 

    // This will add the items sequentially 
    for(let item of dataArray) { 
     await store.add({data:item}); 
    } 
} 
+0

Danke für Ihre Antwort. IDB ist eine interessante Bibliothek, aber ich denke, mit IndexedDB kann ich ohne unnötige Wrapper arbeiten. Auch Problem dieser Bibliothek, dass es den Fehler nicht abfängt, wenn IndexedDB blockiert. Ja, mein Ziel ist Chrome, aber ich möchte nicht erwarten, mein Code sollte auch in anderen Browsern funktionieren, außerdem warte/asynch in der Beta jetzt und arbeite langsam. – Greg

+0

@Greg - async/erwarten sind Teil der kommenden Spezifikation, sie sind nicht langsamer als Versprechen, da sie im Grunde nur diese Funktionalität ausführen. Mit TypeScript können Sie sie verwenden und sie werden zu etwas übertragen, das IE ausführen kann. Ich denke du kannst mit Babel auch, obwohl ich es nicht selbst gemacht habe. Ich bin mir nicht sicher, was Sie damit meinen, keine Fehler zu fangen - das ist nicht das, was es tun soll, es macht nur Callback-Funktionen mit Versprechen. Sie Fehler in Ihrem eigenen Code mit dem Ergebnis des Versprechens oder durch das Umwickeln der Wartezeit in einem regulären Versuch zu fangen. – Keith

+0

Wahrscheinlich hast du recht mit dem Warten/Async, aber normalerweise im Anfang neue Funktionen ist nicht optimiert. Zum Beispiel arbeiteten einheimische Promises schlechter als Polifills. Ereignis "blockiert" wird erstellt, wenn eine Verbindung geöffnet wird, und wir versuchen, mehr zu tun. Und ich denke, dass dieses Ereignis ausgelöst wird, wenn zwei gleichzeitige Transaktion widersprüchlich ist. Und Frage, wie diesen Fehler vermeiden. – Greg