Метод iterate в localForage
предназначен для последовательного обхода всех ключ–значение пар в
хранилище. Его поведение определяется не только самим методом, но и
строгой сигнатурой callback-функции, через которую происходит доступ к
данным на каждой итерации.
Базовая форма вызова выглядит следующим образом:
localforage.iterate(iteratorCallback, successCallback);
или в расширенном виде с обработкой ошибки через Promise:
localforage.iterate(iteratorCallback)
.then(successCallback)
.catch(errorCallback);
Главный параметр метода iterate — это функция-итератор,
которая вызывается для каждого элемента хранилища.
function iteratorCallback(value, key, iterationNumber) {
// логика обработки каждого элемента
}
value Содержит значение, сохранённое в хранилище по текущему ключу. Тип данных не фиксирован — это может быть строка, объект, массив, число или сериализованная структура, в зависимости от используемого драйвера и настроек сериализации.
key Строковый ключ текущего элемента. Используется для идентификации записи в хранилище. Позволяет связывать значение с его оригинальным идентификатором.
iterationNumber Порядковый номер текущей итерации,
начиная с 1. Важно учитывать, что это не индекс массива, а
логический счётчик прохода по записям.
Функция iteratorCallback вызывается в контексте,
привязанном к экземпляру localForage:
this === localforageInstance
Это позволяет внутри callback обращаться к методам экземпляра, например:
localforage.iterate(function (value, key, iterationNumber) {
console.log(this.driver()); // доступ к текущему драйверу
});
Контекст полезен при необходимости динамически взаимодействовать с настройками хранилища во время обхода.
После завершения итерации (когда все записи обработаны), может быть вызван второй callback:
function successCallback() {
// выполнение после завершения iterate
}
Он не получает аргументов и служит сигналом полного завершения обхода. Однако в современных реализациях чаще используется Promise:
localforage.iterate(iteratorCallback).then(() => {
// завершение обхода
});
Возвращаемое значение iteratorCallback
игнорируется механизмом iterate. Никакое
значение, возвращённое из функции, не влияет на поток выполнения или
результат метода.
localforage.iterate((value, key) => {
return value; // не используется библиотекой
});
Порядок обхода элементов зависит от используемого драйвера хранения:
Следовательно, iterationNumber отражает порядок обхода,
но не обязательно порядок вставки данных.
В iterate отсутствует встроенный механизм досрочного
выхода через break или return false.
Типичное поведение:
Единственный способ прервать выполнение — генерация ошибки:
localforage.iterate((value, key, iterationNumber) => {
if (key === "stopKey") {
throw new Error("Прерывание итерации");
}
});
Это приводит к переходу в catch и прекращению
обхода.
Несмотря на синхронную форму callback, сам iterate
работает асинхронно:
Это особенно важно при больших объёмах данных, где IndexedDB может возвращать значения пакетами.
При использовании сериализации (например, JSON):
Пример:
localforage.setItem("user", { name: "Alex", age: 30 });
localforage.iterate((value, key) => {
// value будет объектом { name: "Alex", age: 30 }
});
Сигнатура:
(value, key, iterationNumber)
является стабильной и не менялась в основных версиях localForage. Это позволяет писать универсальные обработчики, не зависящие от конкретного драйвера.
Для строгих сред можно представить сигнатуру следующим образом:
type IterateCallback<T> = (
value: T,
key: string,
iterationNumber: number
) => void;
Метод:
iterate<T>(
iteratorCallback: IterateCallback<T>
): Promise<void>;
Если внутри iteratorCallback возникает исключение:
Это делает обработку ошибок критически важной при работе с большими наборами данных.
Если хранилище не содержит записей:
iteratorCallback не вызывается ни разуsuccessCallback (или .then) выполняется
сразуlocalforage.iterate(() => {
// не выполнится
}).then(() => {
// выполнится сразу
});
Изменение данных во время итерации:
Это делает iterate чувствительным к конкурентным
изменениям хранилища.
Фактическая модель вызова можно представить так:
for (let i = 0; i < storage.length; i++) {
iteratorCallback(value, key, i + 1);
}
Но в реальности реализация абстрагирована и зависит от backend-хранилища, а не от простого массива.
Ключевая форма, которую следует фиксировать при работе:
localforage.iterate(function (value, key, iterationNumber) {
// обработка элемента
}, function () {
// завершение итерации
});
или Promise-вариант:
localforage.iterate((value, key, iterationNumber) => {
// обработка
}).then(() => {
// завершено
});