Attendez que openCursor se termine dans IndexedDB
-
24-12-2019 - |
Question
J'ai ce code :
html5DB.indexedDB.addSomething = function(foo) {
var db = html5DB.indexedDB.db;
var trans = db.transaction(["something"], "readwrite");
var store = trans.objectStore("something");
var isExisting = IsAlreadyExist(foo);
// How to wait for that instruction to finish?
if (!isExisting){
var request = store.put({
"text": foo,
"timeStamp" : new Date().getTime()
});
}
};
J'essaie de comprendre comment puis-je attendre la fonction IsAlreadyExist
pour finir.Cette fonction ouvre un curseur pour parcourir le magasin d'objets afin de déterminer si une valeur particulière existe.
En fait, il n'y a pas d'erreur, mais je n'arrive pas à accéder au code à l'intérieur du if (!isExisting)
car la valeur de la variable ne change jamais.
Voici le code de cette deuxième fonction :
function IsAlreadyExist(foo){
var db = html5DB.indexedDB.db;
var objectStore = db.transaction("something").objectStore("something");
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
if (cursor.value.text == foo)
return true;
cursor.continue();
}
};
return false;
}
Existe-t-il un moyen d'attendre la fin de l'exécution ?Ou peut-être que ce n'est pas une bonne façon de procéder pour vérifier si une valeur existe ?
La solution
Comme IndexedDB est une API asynchrone, vous devez attendre que les opérations soient terminées à l'aide de rappels.
Tout d'abord, nous devons refactoriser le IsAlreadyExist
méthode:
function IsAlreadyExist(foo, oncomplete) {
var db = html5DB.indexedDB.db;
var transaction = db.transaction("something");
var objectStore = transaction.objectStore("something");
var exists = false;
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
if (cursor.value.text == foo) {
exists = true;
return;
}
cursor.continue();
}
};
transaction.oncomplete = function () {
oncompleted(exists);
};
}
Nous allons maintenant refactoriser votre autre méthode :
html5DB.indexedDB.addSomething = function(foo) {
IsAlreadyExist(foo, function (isExisting) {
if (!isExisting){
var db = html5DB.indexedDB.db;
var trans = db.transaction(["something"], "readwrite");
var store = trans.objectStore("something");
var request = store.put({
"text": foo,
"timeStamp" : new Date().getTime()
});
}
});
};
Vous verrez donc ici que nous passons la fonction à exécuter lorsque la recherche du curseur est effectuée en tant que rappel, qui reçoit un argument du statut.
Cela peut commencer à devenir un peu moche, c'est pourquoi PromesseLes sont populaires en JavaScript.J'ai écrit un wrapper pour IndexedDB qui utilise une API basée sur Promise appelée db.js.