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

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


Основная сигнатура

В JavaScript-реализации localForage метод имеет следующую форму:

localforage.getItem(key)

Где:

  • key — строка, идентификатор значения в хранилище

Возвращаемое значение — Promise, который разрешается в сохранённое значение или null, если ключ отсутствует.


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

Для понимания внутренних типов и поведения удобнее рассматривать строго типизированную форму:

getItem<T = any>(key: string): Promise<T | null>

Расширенная версия с учетом callback-совместимости:

getItem<T = any>(
  key: string,
  callback?: (err: any, value: T | null) => void
): Promise<T | null>

Параметры метода

key

Тип: string

Ключ, по которому происходит чтение данных.

Особенности:

  • должен совпадать с ключом, использованным в setItem
  • чувствителен к регистру
  • не поддерживает вложенные пути (user.name не интерпретируется как путь)

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

Метод всегда возвращает:

Promise<T | null>

Возможные результаты:

  • T — значение, восстановленное из хранилища
  • null — ключ отсутствует
  • Error (reject) — ошибка драйвера или доступа к хранилищу

Поведение сериализации

localForage автоматически сериализует и десериализует данные.

При записи:

localforage.setItem("user", { name: "Alex" })

данные сохраняются в сериализованном виде (JSON или внутренний формат IndexedDB).

При чтении:

const user = await localforage.getItem("user");

возвращается уже восстановленный объект:

{ name: "Alex" }

Важно:

  • функции внутри объектов не сохраняются
  • undefined значения внутри структуры могут быть потеряны
  • Date, Blob, ArrayBuffer поддерживаются частично через встроенные механизмы драйверов

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

Если ключ отсутствует:

const value = await localforage.getItem("missing");
console.log(value); // null

Это важное отличие от localStorage, где возвращается строка "null" или undefined через каст.


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

getItem всегда асинхронен вне зависимости от используемого драйвера.

Причина:

  • IndexedDB — асинхронный API
  • унификация поведения всех драйверов

Даже если выбран localStorage как fallback-драйвер, операция всё равно оборачивается в Promise.


Примеры использования

Базовое получение значения

localforage.getItem("token").then(token => {
  console.log(token);
});

Использование async/await

async function loadSession() {
  const session = await localforage.getItem("session");
  return session;
}

Проверка существования данных

const data = await localforage.getItem("cache");

if (data === null) {
  console.log("Данные отсутствуют");
}

Получение сложных объектов

const settings = await localforage.getItem("settings");

if (settings) {
  console.log(settings.theme);
  console.log(settings.language);
}

Callback-режим (устаревший стиль)

localForage сохраняет обратную совместимость с callback API:

localforage.getItem("key", (err, value) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(value);
});

Особенности:

  • callback выполняется после завершения асинхронной операции
  • Promise всё равно возвращается
  • рекомендуется избегать смешивания callback и Promise в одном коде

Типизация результата

Использование дженериков позволяет явно задавать ожидаемый тип:

interface User {
  id: number;
  name: string;
}

const user = await localforage.getItem<User>("user");

Это улучшает:

  • автодополнение
  • контроль типов
  • читаемость кода

Отличия поведения в разных драйверах

IndexedDB (основной драйвер)

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

WebSQL (устаревший)

  • ограниченная поддержка в старых браузерах
  • аналогичное поведение API

localStorage (fallback)

  • данные хранятся как строки
  • ограничения по размеру (~5–10MB)
  • медленнее при больших объёмах данных

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

Метод может отклонить Promise в случаях:

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

Пример обработки:

try {
  const value = await localforage.getItem("data");
} catch (err) {
  console.error("Ошибка чтения:", err);
}

Внутренний механизм работы

При вызове getItem происходит цепочка операций:

  1. Определение активного драйвера

  2. Поиск ключа в соответствующем backend:

    • IndexedDB object store
    • WebSQL table
    • localStorage key
  3. Чтение сериализованного значения

  4. Десериализация через внутренний serializer

  5. Возврат результата через Promise


Особенности работы с null

Важно различать:

  • null как отсутствие значения
  • undefined как невалидное состояние (не сохраняется напрямую)

Пример:

await localforage.setItem("a", null);
const value = await localforage.getItem("a");
console.log(value); // null

Поведение при параллельных запросах

getItem безопасен при конкурентных вызовах:

localforage.getItem("key1");
localforage.getItem("key1");
localforage.getItem("key1");

Все запросы читают одно и то же состояние без блокировок на уровне API.

Однако поведение может зависеть от драйвера IndexedDB, где операции выполняются в очереди транзакций.


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

Факторы влияния:

  • размер объекта
  • тип драйвера
  • наличие индексов (в IndexedDB)
  • частота обращений

Оптимизация достигается за счёт:

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

Частые ошибки использования

Использование без await

const data = localforage.getItem("key");

Результат:

  • data будет Promise, а не значение

Ожидание строки вместо объекта

const value = await localforage.getItem("key");
// ожидание string, но получен object

Решается типизацией или явной обработкой структуры.


Предположение о синхронности

let value;
localforage.getItem("key").then(v => value = v);
console.log(value); // undefined

Совместимость

Метод поддерживается во всех современных браузерах:

  • Chrome
  • Firefox
  • Edge
  • Safari

Также работает в:

  • Electron
  • Progressive Web Apps
  • некоторых WebView-окружениях

Поведение в условиях ограничений браузера

В приватном режиме:

  • IndexedDB может быть ограничен
  • localStorage может быть недоступен
  • localForage автоматически переключается на доступный драйвер, если возможно

При полной блокировке storage API метод возвращает ошибку через reject.


Взаимодействие с другими методами

getItem тесно связан с:

  • setItem — запись данных
  • removeItem — удаление ключа
  • clear — очистка хранилища
  • keys — перечисление ключей

Типичный поток:

await localforage.setItem("a", 1);
const a = await localforage.getItem("a");
await localforage.removeItem("a");

Обобщённая логика сигнатуры

Фактически метод объединяет три слоя:

  • API-уровень (Promise-based)
  • драйвер хранения (IndexedDB/WebSQL/localStorage)
  • слой сериализации данных

Именно это делает его поведение универсальным и независимым от платформы.