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

Idb-keyval — это минималистичная обертка над IndexedDB, обеспечивающая удобное хранение данных в браузере с использованием ключ-значение. Одним из ключевых аспектов работы с любой базой данных является обработка сценариев, когда запрашиваемый ключ отсутствует. В Idb-keyval эта ситуация обрабатывается предсказуемым и лаконичным образом, что позволяет писать безопасный и устойчивый код.


Получение значения по отсутствующему ключу

Метод get используется для извлечения значения по ключу:

import { get } from 'idb-keyval';

const value = await get('nonexistentKey');
console.log(value); // null

Ключевой момент: если указанный ключ отсутствует в хранилище, get возвращает null. Это поведение отличается от некоторых других API, где может выбрасываться исключение при отсутствии значения.

  • Возвращаемое значение всегда асинхронное, через Promise.
  • undefined никогда не используется в качестве маркера отсутствия ключа.

Проверка наличия ключа

Для проверки существования ключа без извлечения значения можно использовать комбинацию get и проверки на null:

const exists = (await get('maybeKey')) !== null;
console.log(exists); // true или false

Если необходима только проверка факта существования ключа, дополнительной функции вроде has в стандартной библиотеке idb-keyval нет, поэтому рекомендуется использовать именно такое сравнение.


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

get

  • Возвращает null.
  • Не выбрасывает исключения.
  • Поддерживает любые типы ключей: строки, числа, объекты, при условии сериализуемости.

del

import { del } from 'idb-keyval';

await del('missingKey'); 
// Ошибок нет, операция просто игнорируется
  • Удаление отсутствующего ключа выполняется безопасно.
  • Метод del является идемпотентным: повторное удаление того же ключа не вызывает ошибок и не изменяет состояние хранилища.

update

При обновлении значения с использованием функции, если ключ отсутствует, поведение зависит от того, как реализована функция обновления:

import { update } from 'idb-keyval';

await update('counter', n => (n || 0) + 1);
  • Если ключ отсутствует, update передаст undefined в функцию.
  • В примере выше используется оператор || 0, чтобы обработать отсутствующее значение и задать начальное число.
  • Это обеспечивает гибкость для инкрементов, накопления данных и других операций, зависящих от текущего состояния ключа.

Особенности обработки отсутствующих ключей

  1. Прогнозируемость: всегда возвращается null или undefined внутри функций обновления, исключения не выбрасываются.
  2. Идемпотентность: операции del и частично update не нарушают консистентность при повторном вызове.
  3. Совместимость с любыми типами данных: ключи могут быть строками, числами или сериализуемыми объектами; отсутствие ключа всегда обрабатывается одинаково.

Практические примеры

Инициализация данных при первом обращении:

await update('visits', count => (count ?? 0) + 1);
  • Если ключ 'visits' отсутствует, функция получает undefined.
  • Оператор ?? 0 задаёт начальное значение.

Удаление условного ключа:

const keyToDelete = 'tempData';
if ((await get(keyToDelete)) !== null) {
    await del(keyToDelete);
}
  • Проверка на null позволяет безопасно удалить ключ только при его наличии, хотя вызов del без проверки также безопасен.

Массив данных с инициализацией:

await update('items', arr => (arr ?? []).concat('newItem'));
  • Если 'items' отсутствует, создается пустой массив, и в него добавляется элемент.
  • Такой подход позволяет создавать коллекции «на лету» без ошибок.

Рекомендации по использованию

  • Всегда учитывать, что get возвращает null для отсутствующих ключей.
  • При использовании update учитывать возможность передачи undefined в функцию и корректно задавать начальные значения.
  • Не полагаться на выброс исключений для отсутствующих ключей — логика должна быть построена на проверке null или безопасной инициализации данных.

Обеспечение устойчивости к отсутствующим ключам делает работу с idb-keyval простой и предсказуемой. Следование этим правилам позволяет создавать приложения с безопасной обработкой хранилища и минимизировать ошибки при работе с IndexedDB.