Использование Promises для итеративного удаления элементов в IndexedDb
Я немного новичок в обещаниях, поэтому решение может быть тривиальным / синтаксическим.
Моя цель при хранении мультимедиа - увидеть, установлена ли квота, и - при необходимости - удалить элементы из store
пока у нас нет места.
Моя попытка здесь, но моя самая большая боль в том, что while
цикл - выяснение того, как ждать, пока элемент будет удален, чтобы заново оценить, следует ли продолжать удаление:
const store = database.transaction(storeName, "readwrite").objectStore(storeName);
while (storageUsedInGb > storageQuotaInGb) {
// problem: pause loop here
const latestMediaRequest = store.get(latestMediaGuid);
latestMediaRequest.onsuccess = function(event) {
var deleteRequest = store.delete(latestMediaGuid);
deleteRequest.onsuccess = function () {
storageUsedInGb -= event.target.media.size / 1024 / 1000 / 1000;
// problem: continue loop here
}
deleteRequest.onerror = reject;
}
latestMediaRequest.onerror = reject;
}
Как я могу сказать, что в то время как цикл ждать, чтобы повторить, пока у меня нет разрешения от latestMediaRequest
а затем deleteRequest
(обновление storageUsedInGb
)?
1 ответ
Решение
Вы можете выполнять асинхронный цикл с рекурсивно вызываемой функцией. Функция может быть немедленно вызванным выражением функции:
const store = database.transaction(storeName, "readwrite").objectStore(storeName);
(function loop(storageUsedInGb) {
if (storageUsedInGb <= storageQuotaInGb) {
// if you are in a promise constructor callback, you will call resolve() here
return; // exit chain of loop calls
}
const latestMediaRequest = store.get(latestMediaGuid);
latestMediaRequest.onsuccess = function(event) {
var deleteRequest = store.delete(latestMediaGuid);
deleteRequest.onsuccess =
loop.bind(null, storageUsedInGb-event.target.media.size / 1024 / 1000 / 1000);
deleteRequest.onerror = reject;
}
latestMediaRequest.onerror = reject;
})(storageUsedInGb); // call immediately