Использование 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
Другие вопросы по тегам