2012-06-22 3 views
5

ich zwei verschiedene Ereignisse für den Rückruf, wenn die IndexedDB Transaktion beendet oder erfolgreich zu reagieren:Indexeddb: Unterschiede zwischen onsuccess und oncomplete?

Sagen wir mal ... db: IDBDatabase Objekt, tr: IDBTransaction Objekt, os: IDBObjectStore Objekt

tr = db.transaction(os_name,'readwrite'); 
os = tr.objectStore(); 

Fall 1:

r = os.openCursor(); 
r.onsuccess = function(){ 
    if(r.result){ 
     callback_for_result_fetched(); 
     r.result.continue; 
    }else callback_for_transaction_finish(); 
} 

Fall 2:

tr.oncomplete = callback_for_transaction_finish(); 

Es ist eine Verschwendung, wenn beide ähnlich funktionieren. Kannst du mir sagen, gibt es einen Unterschied zwischen ihnen?

+0

Dies ist eine große Frage – buley

Antwort

8

Während es wahr ist, funktionieren diese Rückrufe in ähnlicher Weise sind sie nicht das gleiche: der Unterschied zwischen onsuccess und oncomplete ist, dass Transaktionen complete aber Anfragen, die sich auf diese Geschäfte gemacht werden, sind successful.

oncomplete ist nur in the spec in Bezug auf eine Transaktion definiert. Eine Transaktion hat keinen Rückruf onsuccess.

+0

meinten Sie, dass, wenn eine Transaktion abgeschlossen ist, bedeutet das nicht, die ganze Verarbeitung ist erfolgreich, innit? – Dagon

+2

ja, es bedeutet, dass die Transaktion außerhalb des Geltungsbereichs gegangen ist und – buley

8

Sorry für Aufrichten recht einen alten Faden, aber es ist fragend ein guter Ausgangspunkt ist ...

Ich habe eine ähnliche Frage gesucht, aber in einem etwas anders Anwendungsfall und fand tatsächlich keine gute Antworten oder sogar eine irreführende.

Denken Sie an einen Anwendungsfall, wenn Sie mehrere schreiben müssen in den Objektspeicher von sogar in mehrere. Sie definitiv wollen nicht verwalten jedes einzelne Schreiben und es ist eigene Erfolg und Fehlerereignisse. Das ist die Bedeutung der Transaktion und das ist die (richtige) Umsetzung für IndexedDB:

var trx = dbInstance.transaction([storeIdA, storeIdB], 'readwrite'), 
    storeA = trx.objectStore(storeIdA), 
    storeB = trx.objectStore(storeIdB); 

    trx.oncomplete = function(event) { 
     // this code will run only when ALL of the following requests are succeed 
     // and only AFTER ALL of them were processed 
    }; 
    trx.onerror = function(error) { 
     // this code will run if ANY of the following requests will fail 
     // and only AFTER ALL of them were processed 
    }; 

    storeA.put({ key:keyA, value:valueA }); 
    storeA.put({ key:keyB, value:valueB }); 
    storeB.put({ key:keyA, value:valueA }); 
    storeB.put({ key:keyB, value:valueB }); 

Clue zu diesem Verständnis ist spec in der folgenden Aussage von W3C gefunden werden:

Um zu bestimmen, Wenn eine Transaktion erfolgreich abgeschlossen wurde, hören Sie das vollständige Ereignis der Transaktion und nicht das Erfolgsereignis einer bestimmten Anforderung, weil die Transaktion möglicherweise noch fehlschlägt, nachdem das Erfolgsereignis ausgelöst wurde.

+0

genau das beging, wonach ich gesucht habe. Ich nehme an objectStore.onsuccess und objectStore.oncomplete kann auch für multi .add,. get, .put, etc ... am gegebenen Objektspeicher. –

2

Ich würde nur warnen, dass es keine garentee ist, dass eine erfolgreiche trx.oncomplete immer bedeutet, dass die Daten auf die Platte/Datenbank geschrieben wurden:

Wir sind ein Problem mit trx.oncomplete zu sehen, wo die Daten nicht in die Datenbank auf der Festplatte geschrieben. FireFox hat eine Erklärung von dem, was sie verursacht, das dieses Problem hier verursacht: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

Es scheint, dass Windows/Edge das gleiche Problem hat. Grundsätzlich gibt es keine Garantie dafür, dass Ihre App Daten in die Datenbank geschrieben hat, wenn der Benutzer entscheidet, das Gerät zu beenden oder abzuschalten. Wir haben sogar versucht, in einigen Fällen bis zu 15 Minuten zu warten, bevor wir heruntergefahren haben und die Daten nicht gesehen haben. Für mich würde ich immer sicherstellen wollen, dass ein Datenschreiben abgeschlossen ist und festgeschrieben ist.

Gibt es andere Lösungen für eine echte persistenten Datenbank oder Erweiterungen des IndexedDB über FF experimentelle Add ...