Поведение метода iterate в localForage
строится вокруг последовательного обхода всех ключей хранилища с
передачей текущего значения, ключа и номера итерации в callback-функцию.
Особый интерес представляет механизм прерывания обхода через возврат
значения из callback, который превращает обычную итерацию в управляемый
процесс с возможностью раннего выхода.
В стандартном режиме iterate проходит по всем элементам
хранилища до завершения коллекции ключей. Однако callback-функция может
повлиять на поток выполнения, возвращая значение, которое трактуется как
сигнал остановки.
Ключевое правило поведения:
если callback возвращает любое значение, отличное от
undefined, итерация немедленно прекращается
При этом возвращаемое значение становится результатом всего вызова
iterate.
Такой подход позволяет использовать iterate не только
как средство обхода, но и как механизм поиска с ранним выходом.
Callback в iterate имеет следующую логическую
структуру:
value — значение, сохранённое по ключуkey — ключ элементаiterationNumber — порядковый номер обходаИменно возвращаемое значение callback определяет судьбу дальнейшей итерации.
undefined — продолжить обходiterateТаким образом callback одновременно выполняет две функции:
При возврате значения происходит разрыв внутреннего цикла обхода. В
зависимости от драйвера хранения (IndexedDB, WebSQL или localStorage),
localForage завершает текущую цепочку промисов и резолвит
основной Promise с переданным значением.
Важно, что остановка происходит синхронно относительно логики итератора, но физическое завершение зависит от реализации драйвера.
localforage.iterate((value, key) => {
if (key === 'session_token') {
return value;
}
});
В данном случае:
session_token возвращается
значениеМеханизм возврата значения принципиально отличается от привычных методов обхода массивов:
forEach в массивах игнорирует returnmap всегда проходит по всем элементамreduce агрегирует результат без возможности
остановкиiterate в localForage сочетает поведение
обхода и контролируемого прерывания, что делает его ближе к циклу
for...of с break, но в асинхронной среде.
Так как localForage работает поверх асинхронных
драйверов, прерывание итерации не является мгновенным в смысле
исполнения JavaScript-цикла. Оно реализуется через цепочку промисов:
При возврате значения последующие шаги просто не планируются.
В качестве возвращаемого значения может использоваться любой тип данных:
string, number,
boolean)nullПрерывание происходит не по типу значения, а по факту его отличия от
undefined.
localforage.iterate((value, key) => {
if (typeof value === 'object' && value.active) {
return { key, value };
}
});
Здесь возвращается объект, содержащий найденные данные, и обход завершается.
Наиболее типичный сценарий — поиск первого элемента, удовлетворяющего условию. Вместо полного обхода всей базы:
localforage.iterate((value, key) => {
if (value === 'target') return key;
});
Как только найдено совпадение, дальнейшие чтения из хранилища прекращаются.
localforage.iterate((value) => {
if (value === null) return true;
});
Здесь итерация используется как проверка условия существования хотя бы одного элемента с нужным свойством.
localforage.iterate((value) => {
if (value.priority > 10) {
return value.id;
}
});
Итерация завершается при достижении первого элемента, удовлетворяющего условию приоритета.
Хотя поведение API унифицировано, внутренние реализации могут отличаться:
Во всех случаях результат одинаков — дальнейшие вызовы callback не происходят.
undefined по
ошибкеЕсли функция неявно возвращает undefined, например при
отсутствии return, итерация продолжится полностью:
localforage.iterate((value) => {
if (value.active) {
value.flag = true;
}
});
Здесь отсутствует явный возврат, поэтому остановки не происходит.
Иногда логика функции может непреднамеренно вернуть значение:
localforage.iterate((value) => {
if (value.active) {
return value.flag = true;
}
});
Присваивание возвращает true, что приведёт к
немедленному прерыванию обхода.
Когда итерация прерывается возвратом значения, итоговый Promise
iterate резолвится этим значением. Это делает
iterate двойственным по природе:
Таким образом, iterate можно рассматривать как функцию
поиска с ленивым завершением.
Использование возврата для остановки накладывает ряд ограничений:
Несмотря на это, механизм остаётся одним из наиболее эффективных способов сокращения операций чтения из хранилища при работе с большими наборами данных.