Библиотека idb-keyval предоставляет минималистичный
интерфейс для работы с IndexedDB в браузере. Она упрощает операции
хранения и извлечения данных, скрывая сложность асинхронного API
IndexedDB. Основные методы включают get, set,
del, update, а также утилиты для работы с
транзакциями и коллекциями данных.
get и метод
setМетод get(key) используется для извлечения значения по
ключу. Он возвращает промис, который резолвится значением из хранилища
или undefined, если ключ отсутствует:
import { get, set } from 'idb-keyval';
await set('username', 'Alice');
const username = await get('username'); // 'Alice'
Метод set(key, value) записывает или обновляет значение
по ключу. Если ключ уже существует, старое значение перезаписывается
новым.
await set('username', 'Bob');
const upd atedUsername = await get('username'); // 'Bob'
Таким образом, комбинация get и set
позволяет реализовать обновление значения вручную: сначала получить
текущее значение, изменить его и записать обратно.
updateМетод upd ate(key, updater) объединяет операции чтения и
записи в одну атомарную операцию. Аргумент updater — это
функция, которая принимает текущее значение ключа и возвращает
новое.
import { upd ate } from 'idb-keyval';
await upd ate('counter', val => (val || 0) + 1);
const counter = await get('counter'); // 1, если ключа не было ранее
Ключевые особенности update:
get и set.update на одном ключе корректно увеличивают
значение, не затирая изменения других процессов.update и последовательности get/se t| Характеристика | get + set |
update |
|---|---|---|
| Количество операций | Две операции (чтение и запись) | Одна атомарная операция |
| Потенциальные состояния гонки | Возможны при параллельных модификациях | Исключены благодаря транзакции |
| Чистота кода | Требуется ручная проверка и модификация | Лаконичный, безопасный синтаксис |
| Поддержка конкурентных обновлений | Нужно вручную реализовывать блокировку | Автоматически управляется библиотекой |
Сценарий 1: Счетчик кликов Использование
последовательности get/se t:
const clicks = await get('clicks') || 0;
await se t('clicks', clicks + 1);
Использование update:
await upd ate('clicks', val => (val || 0) + 1);
Разница становится заметна при нескольких параллельных вызовах. При
get/se t есть риск потерять некоторые инкременты, если они
выполняются почти одновременно. update решает эту проблему
за счет атомарной транзакции.
Сценарий 2: Обновление настроек пользователя Предположим, нужно добавить новое поле в объект настроек:
await upd ate('settings', settings => ({
...settings,
theme: 'dark'
}));
Аналогично через get/se t потребовалось бы:
const settings = await get('settings') || {};
settings.theme = 'dark';
await se t('settings', settings);
update обеспечивает более читаемый и надежный код,
особенно при работе с сложными структурами данных.
Метод update предпочтителен, когда требуется
модифицировать существующее значение в хранилище с сохранением
атомарности и безопасности. Последовательность get/set
подходит для простых операций записи или когда необходимо выполнить
дополнительные проверки между чтением и записью, но требует осторожности
при параллельных обновлениях.
Использование update повышает надежность кода и снижает
вероятность ошибок при одновременном доступе к данным, делая работу с
IndexedDB через idb-keyval более безопасной и удобной.