Метод getItem: получение значения

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


Сигнатура метода

localForage.getItem(key)

Параметры:

  • key — строка, идентификатор элемента, сохранённого ранее через setItem

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

  • Promise<any> — промис, который резолвится значением, связанным с ключом
  • при отсутствии значения возвращается null

Поддерживается также устаревший callback-формат:

localForage.getItem(key, callback)

Базовое поведение

При вызове getItem происходит обращение к текущему драйверу хранения. В зависимости от конфигурации localForage:

  • IndexedDB используется в современных браузерах по умолчанию
  • WebSQL может применяться в старых WebKit-браузерах
  • localStorage используется как fallback при отсутствии других вариантов

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


Пример получения значения

localForage.getItem('user').then(function (value) {
  console.log(value);
});

Современный вариант с async/await:

async function loadUser() {
  const user = await localForage.getItem('user');
  console.log(user);
}

Поведение при отсутствии ключа

Если указанный ключ не существует, результатом будет:

null

Это важное отличие от некоторых низкоуровневых API, где отсутствие ключа может трактоваться как undefined или ошибка.


Тип возвращаемого значения и сериализация

localForage сохраняет данные с использованием механизмов сериализации, зависящих от драйвера:

  • IndexedDB использует structured clone algorithm
  • localStorage и WebSQL используют JSON-сериализацию

При извлечении данных:

  • примитивы возвращаются без изменений
  • объекты восстанавливаются в исходной структуре (в рамках возможностей сериализации)
  • функции, DOM-узлы и нестандартные типы не сохраняются

Пример:

await localForage.setItem('config', {
  theme: 'dark',
  layout: { sidebar: true }
});

const config = await localForage.getItem('config');

Асинхронная модель выполнения

getItem всегда асинхронен, даже если физическое хранилище синхронное. Это приводит к нескольким важным свойствам:

  • вызовы не блокируют основной поток
  • порядок выполнения определяется очередью промисов
  • результат всегда возвращается через Promise

Пример последовательных операций:

localForage.setItem('a', 1);
localForage.getItem('a').then(console.log);
console.log('sync');

Вывод будет:

sync
1

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

При чтении данных возможны ошибки, связанные с:

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

Ошибка передаётся в reject-промис:

localForage.getItem('key')
  .then(value => {
    console.log(value);
  })
  .catch(err => {
    console.error(err);
  });

Callback-версия:

localForage.getItem('key', function (err, value) {
  if (err) {
    console.error(err);
    return;
  }
  console.log(value);
});

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

Поведение getItem может отличаться в деталях в зависимости от драйвера:

IndexedDB

  • поддерживает большие объёмы данных
  • обеспечивает асинхронное чтение на уровне браузера
  • сохраняет сложные структуры данных

localStorage

  • синхронное хранилище, но обёрнуто в Promise
  • ограничение по объёму (обычно ~5–10 MB)
  • данные всегда строки на уровне API

WebSQL

  • устаревший механизм
  • поведение зависит от реализации браузера

Кэширование и производительность

localForage не добавляет явного кэширования поверх драйвера. Каждый вызов getItem обращается к хранилищу напрямую. Это важно учитывать при:

  • частых чтениях одних и тех же ключей
  • работе с большими объектами
  • циклических вызовах внутри рендер-логики

Для оптимизации обычно применяются:

  • локальные переменные
  • мемоизация на уровне приложения
  • минимизация обращений к storage

Особенности работы с ключами

Ключи всегда приводятся к строковому виду. При передаче других типов происходит преобразование:

localForage.getItem(123)

фактически эквивалентно:

localForage.getItem('123')

Это важно при работе с динамически формируемыми идентификаторами.


Параллельные вызовы

Несколько одновременных вызовов getItem не блокируют друг друга:

Promise.all([
  localForage.getItem('a'),
  localForage.getItem('b'),
  localForage.getItem('c')
]).then(console.log);

Каждый запрос выполняется независимо, но фактическая параллельность зависит от драйвера. IndexedDB способен обрабатывать несколько запросов более эффективно, чем localStorage.


Взаимодействие с setItem

getItem часто используется совместно с setItem. Важно учитывать, что операции записи также асинхронны:

await localForage.setItem('session', { id: 10 });
const session = await localForage.getItem('session');

Гарантируется, что при корректном await значение будет доступно после записи.


Особенности работы в различных средах

В браузерах поведение полностью стандартизировано через драйверы localForage. В нестандартных окружениях:

  • в WebView возможны ограничения IndexedDB
  • в приватных режимах Safari возможны ошибки записи/чтения
  • в некоторых старых Android-браузерах IndexedDB может быть нестабилен

В таких случаях библиотека автоматически переключается на доступный драйвер, но результат getItem остаётся единообразным по API.


Использование в типовых сценариях

Чтение пользовательских настроек:

const settings = await localForage.getItem('settings');

Получение кэша данных:

const cache = await localForage.getItem('api_cache_v1');

Загрузка состояния приложения:

const state = await localForage.getItem('app_state');

Поведение при инициализации хранилища

Если getItem вызывается до завершения установки драйвера (setDriver или автоматическая инициализация), операция откладывается до готовности хранилища. Это гарантирует отсутствие необходимости вручную синхронизировать инициализацию и чтение.


Итоговые особенности поведения метода

  • всегда возвращает Promise
  • возвращает null при отсутствии данных
  • работает поверх различных драйверов без изменения API
  • не блокирует основной поток выполнения
  • поддерживает callback-совместимость
  • зависит от возможностей выбранного storage backend