2012-06-22 2 views
5

Io uso due eventi differenti per la richiamata per rispondere quando la transazione IndexedDB finisce o è successo:Indexeddb: differenze tra onsuccess e oncomplete?

Diciamo ... db: oggetto IDBDatabase, tr: oggetto IDBTransaction, os: IDBObjectStore opporsi

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

caso 1:

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

caso 2:

tr.oncomplete = callback_for_transaction_finish(); 

È uno spreco se entrambi funzionano allo stesso modo. Quindi puoi dirmi, c'è qualche differenza tra loro?

+0

Questa è una grande domanda – buley

risposta

8

Mentre è vero questi callback funzionano in modo simile che non sono la stessa cosa: la differenza tra onsuccess e oncomplete è che le transazioni complete ma le richieste, che sono fatte su tali operazioni, sono successful.

oncomplete è definito solo in the spec come correlato a una transazione. Una transazione non ha un callback onsuccess.

+0

volevi dire che quando una transazione è completa, che non significa l'intera elaborazione ha successo, innit? – Dagon

+2

sì, significa che la transazione è andata fuori portata ed è stata commessa – buley

8

dispiace per la raccolta di un vecchio filo abbastanza, ma è in discussione è un buon punto di partenza ...

Ho cercato una domanda simile, ma in un caso po 'diverso utilizzo e in realtà ho trovato nessun buone risposte o anche un fuorviante.

Pensare a un caso d'uso quando è necessario effettuare diverse scritture nell'oggettoStore anche in più di uno. È sicuramente non si desidera che gestisca ogni singola scrittura e gli eventi di successo e di errore. Questo è il significato di operazioni e questa è la (corretta) l'attuazione di esso per 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 }); 

Indizio a questa comprensione si trova nella seguente affermazione del W3C spec:

Per determinare se una transazione è stata completata correttamente, ascolta l'evento completo della transazione anziché l'evento di successo di una particolare richiesta, perché la transazione potrebbe non riuscire ancora dopo l'attivazione dell'evento.

+0

proprio quello che stavo cercando. presumo objectStore.onsuccess, e objectStore.oncomplete può anche essere utilizzato per multi .add,. get, .put, ecc. su un determinato archivio oggetti. –

2

vorrei mettere in guardia solo che non c'è garentee che ottenere un trx.oncomplete successo significa i dati sono stati scritti sul disco/database:

Stiamo assistendo ad un problema con trx.oncomplete in cui i dati sono non viene scritto sul db su disco. FireFox ha una spiegazione di ciò che hanno fatto che sta causando questo problema qui: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

Sembra che anche Windows/Edge abbia lo stesso problema. Fondamentalmente, non vi è alcuna garanzia che la tua app abbia i dati scritti sul database, se/quando l'utente decide di uccidere o spegnere il dispositivo. Abbiamo persino provato ad attendere fino a 15 minuti prima di arrestare in alcuni casi e non ho visto i dati scritti. Per quanto mi riguarda, vorrei sempre assicurarmi che una scrittura di dati sia completa e sia stata commessa.

Esistono altre soluzioni per una vera e propria banca dati persistente, o miglioramenti al di là IndexedDB FF add sperimentale ...