2012-06-22 11 views
5

używam dwóch różnych imprez dla zwrotnego reagować, gdy transakcja kończy IndexedDB lub jest udany:Indexeddb: różnice między onsuccess i oncomplete?

Powiedzmy ... db: obiekt IDBDatabase, tr: IDBTransaction obiekt, os: IDBObjectStore sprzeciw

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

przypadek 1:

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

przypadek 2:

tr.oncomplete = callback_for_transaction_finish(); 

To jest marnowanie, jeśli oba z nich działają podobnie. Więc możesz mi powiedzieć, czy jest jakaś różnica między nimi?

+0

To jest wielkie pytanie – buley

Odpowiedz

8

Prawdą te wywołania zwrotne działają podobnie nie są takie same: różnica między onsuccess i oncomplete jest to, że transakcje complete ale wnioski, które są dokonywane na tych transakcjach są successful.

oncomplete jest zdefiniowany tylko w the spec jako powiązany z transakcją. Transakcja nie ma wywołania zwrotnego onsuccess.

+0

pan miał na myśli, że kiedy transakcja zostanie zakończona, to nie znaczy, całe przetwarzanie zakończyło się sukcesem, innit? – Dagon

+2

tak, oznacza to, że transakcja wykroczyła poza zakres i została zatwierdzona – buley

8

Przepraszamy za wzbudza dość stary wątek, ale pytający jest dobrym punktem wyjścia ...

Szukałem na podobne pytanie, ale w nieco inny przypadek użycia i rzeczywiście znaleziono żadnych dobrych odpowiedzi lub nawet wprowadzających w błąd.

Pomyśl o przypadku użycia, gdy musisz zrobić w magazynie obiektów nawet na kilka. Zdecydowanie nie chcesz, aby zarządzał każdym pojedynczym napisem i jego własnymi sukcesami i błędami. Taki jest sens transakcji i to jest (właściwa) realizacja to dla 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 do tego zrozumienia można znaleźć w poniższym zestawieniu W3C spec:

Do ustalenia Jeśli transakcja została pomyślnie zakończona, należy odsłuchać kompletne zdarzenie transakcji transakcji , a nie zdarzenie powodzenia określonego żądania, ponieważ transakcja może się nie powieść po uruchomieniu zdarzenia powodzenia.

+0

dokładnie to, czego szukałem. Zakładam, że obiekty objectStore.onsuccess i objectStore.oncomplete mogą być również używane dla wielu .add,. get, .put, etc ... na danym magazynie obiektów. –

2

Chciałbym tylko ostrzec, że nie ma garentee że coraz udanej trx.oncomplete oznacza, że ​​dane zostały zapisane na dysku/bazy danych:

Widzimy problem z trx.oncomplete gdzie dane są nie zapisywane do bazy danych na dysku. FireFox ma wyjaśnienie, co zrobili, co powoduje ten problem: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

Wygląda na to, że Windows/Edge ma ten sam problem. Zasadniczo nie ma gwarancji, że Twoja aplikacja będzie zawierała dane zapisane w bazie danych, jeśli/kiedy użytkownik zdecyduje się zabić lub wyłączyć urządzenie. Próbowaliśmy nawet czekać do 15 minut przed wyłączeniem w niektórych przypadkach i nie widzieliśmy zapisanych danych. Dla mnie zawsze chciałbym mieć pewność, że zapis danych zakończy się i zostanie zatwierdzony.

Czy istnieją inne rozwiązania dla prawdziwego uporczywego bazy danych lub innych akcesoriów do IndexedDB poza FF dodatku eksperymentalnej ...