Полная сигнатура length

Метод определения количества записей в хранилище является одной из базовых операций при работе с асинхронными хранилищами браузера. В контексте localForage он реализует унифицированный интерфейс поверх IndexedDB, WebSQL и localStorage, скрывая различия между ними и предоставляя предсказуемое поведение.

Метод length имеет две основные формы вызова:

localForage.length(callback)

и промис-ориентированную форму:

localForage.length().then(numberOfKeys => { ... })

Также возможна асинхронная обработка через async/await:

const count = await localForage.length();

Сигнатура с callback

length(
  callback?: (err: any, numberOfKeys: number) => void
): void

Сигнатура с Promise

length(): Promise<number>

Описание поведения

Метод возвращает количество ключей, сохранённых в текущем экземпляре localForage. Под ключами понимаются все элементы, записанные через setItem, которые ещё не были удалены через removeItem или очистку через clear.

Подсчёт выполняется асинхронно независимо от используемого драйвера:

  • IndexedDB — чтение количества записей через cursor/metadata
  • WebSQL — выполнение COUNT(*) запроса
  • localStorage — перебор ключей с префиксом instance

Возвращаемое значение

При использовании Promise возвращается число:

number

Оно отражает текущее количество элементов в хранилище.

При использовании callback значение передаётся вторым аргументом:

(err, numberOfKeys) => {}

где:

  • err — объект ошибки или null
  • numberOfKeys — количество записанных элементов

Особенности асинхронной модели

Метод не выполняется синхронно, даже если драйвер физически способен предоставить результат мгновенно (например, localStorage). Это сделано для унификации API и предотвращения различий в поведении между средами.

Каждый вызов length создаёт асинхронную операцию, которая может быть отложена в очередь выполнения событийного цикла.

Влияние выбранного драйвера

Поведение метода напрямую зависит от активного драйвера, но результат остаётся одинаковым по смыслу.

IndexedDB

В IndexedDB подсчёт обычно выполняется через перебор курсора или использование встроенных возможностей подсчёта записей. В крупных базах данных операция может иметь стоимость O(n), если оптимизированный счётчик не используется.

WebSQL

При использовании WebSQL выполняется SQL-запрос вида:

SEL ECT COUNT(*) FR OM store;

Это наиболее предсказуемый вариант с точки зрения производительности.

localStorage

В случае localStorage выполняется перебор ключей объекта window.localStorage, с фильтрацией по префиксу, соответствующему экземпляру localForage.

Поведение при пустом хранилище

Если в хранилище отсутствуют записи, метод возвращает:

0

Ошибка в этом случае не генерируется, так как отсутствие данных считается валидным состоянием.

Обработка ошибок

Ошибки могут возникать в следующих случаях:

  • отказ доступа к IndexedDB (например, режим приватного просмотра)
  • квота хранилища недоступна или повреждена
  • внутренняя ошибка драйвера
  • неконсистентное состояние базы данных

При использовании Promise ошибка передаётся через reject:

localForage.length().catch(err => {
  // обработка ошибки
});

При использовании callback ошибка передаётся первым аргументом.

Производительность

Операция length считается относительно лёгкой, но её стоимость не является строго константной во всех драйверах.

  • IndexedDB: потенциально зависит от размера object store
  • WebSQL: оптимизированный COUNT
  • localStorage: линейный перебор ключей

При частых вызовах в горячих циклах возможны накладные расходы, особенно в localStorage-режиме.

Согласованность данных

Так как localForage использует асинхронную модель, возможна ситуация, когда значение length отражает состояние хранилища на момент завершения запроса, а не на момент его вызова.

Пример:

const p1 = localForage.setItem('a', 1);
const p2 = localForage.length();

Результат length может не учитывать setItem, если операция записи ещё не завершена.

Связь с другими методами

Метод тесно связан с:

  • setItem — увеличивает количество ключей при добавлении нового
  • removeItem — уменьшает количество ключей при удалении
  • clear — обнуляет результат до нуля
  • keys — предоставляет список ключей, на основе которого можно вычислить длину вручную

Использование в потоках данных

В сценариях, где localForage используется как кэш или слой хранения состояния приложения, length часто применяется для:

  • оценки объёма данных
  • контроля заполненности кэша
  • принятия решений о необходимости очистки
  • мониторинга роста хранилища

Однако метод не предоставляет информации о размере данных в байтах, только о количестве записей.

Поведение при смене драйвера

Если во время работы приложения происходит переключение драйвера через setDriver, метод length начинает использовать новый механизм подсчёта без сохранения промежуточного состояния. Это может привести к различиям в значении, если структуры хранения отличаются между драйверами.

Потокобезопасность

Хотя JavaScript в браузере однопоточный, асинхронные операции могут приводить к конкурентным изменениям состояния. В момент выполнения length данные могут быть изменены другими операциями записи или удаления, что делает результат актуальным только на момент завершения запроса.

Практические нюансы реализации

Внутри localForage метод length является частью адаптерного слоя. Каждый драйвер реализует собственную стратегию подсчёта:

  • IndexedDBAdapter реализует через cursor iteration или count API
  • WebSQLAdapter использует SQL aggregation
  • LocalStorageAdapter фильтрует ключи по namespace

Над этим слоем находится единый интерфейс, который нормализует результат в number и оборачивает его в Promise или callback-стиль в зависимости от вызова.

Типичные сценарии использования

Метод применяется в системах, где важно знать объём хранимых сущностей:

  • офлайн-кэширование данных
  • очередь синхронизации
  • хранение пользовательских черновиков
  • локальные списки задач

При этом он не предназначен для анализа содержимого или глубокой инспекции данных — только для количественной оценки состояния хранилища.