В посте Сохранение состояния в JavaScript - wora / cache-persist - Начало работы я покажу вам, как родился wora / cache-persist и как легко его использовать в ваших приложениях.

Сегодня я хочу рассказать вам с помощью исходного кода, как Cache использует состояние и как он управляет обменом данными (чтение / запись данных) с хранилищем, обеспечивающим высокая эффективность.

Чтение данных

Чтение данных полностью управляется объектом Кэш с помощью поля data, простого JavaScript Object и его синхронного функции чтения.
Это означает, что приложение считывает всю информацию с той же производительностью, что и простой кэш в памяти!

Запись данных

Данные записываются за два момента: первый, выполняется только один раз, когда кеш должен быть инициализирован, а второй когда приложение использует функции записи, предоставляемые кешем.

Посылка

Чтобы решить проблему записи данных, необходимо создать предпосылку для некоторых внутренних объектов и концепций библиотеки: StorageProxy, хранилище и мутации

  • StorageProxy

StorageProxy - это внутренний объект библиотеки, задача которого - сделать взаимодействие с хранилищем прозрачным для пользователей. Он реализует интерфейс IStorageHelper.

  • Хранилище

Хранилище - это внутренний объект библиотеки, который уважает этот интерфейс таким образом, чтобы скрыть сложность и специфику используемого реального хранилища:

В настоящее время реализовано хранилище для localStorage, sessionStorage, AsyncStorage и indexedDB. Если необходимо использовать другое хранилище, просто создайте объект, реализующий интерфейс ICacheStorage, и настройте его в параметре storage [Необязательно] [По умолчанию: localStorage / AsyncStorage]

  • Мутации

Библиотека позволяет вам настроить, как данные должны быть изменены перед записью / чтением из хранилища, с помощью следующих двух опций:

mutateKeys: [Необязательно] с помощью этой опции вы можете настроить массив функций мутации, которые будут выполняться для изменения ключей во время записи / чтения в хранилище. Параметр префикс вставит функцию prefixLayer как первую в списке.

mutateValues: [Необязательно] с помощью этой опции вы можете настроить массив функций мутации, которые будут выполняться для изменения значений во время записи / чтения в хранилище. Параметр сериализации вставит функцию jsonSerialize последней в списке.

Можно реализовать любую другую мутацию, реализовав интерфейсы, описанные ниже:

  • Заданная функция будет вызвана перед записью в хранилище.
  • Функция get будет вызываться после чтения в хранилище.

В дополнение к функциям jsonSerialize и prefixLayer в библиотеке уже присутствует еще одна функция мутации - filterKeys, которая позволяет вы должны определить функцию, чтобы определить, какие ключи сохраняются.

Ниже мы можем увидеть, как эти два параметра используются StorageProxy для преобразования массива в единую функцию мутации с помощью функции compose:

Что ж, теперь мы готовы посмотреть, как выполняется запись данных в библиотеку .

Инициализация кеша

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

Его исполнение состоит из:

  • promisesRestored используется, чтобы избежать многократного восстановления
  • запрос ранее сохраненного состояния у StorageProxy, через его функцию восстановления
  • выполнение функции mergeState между постоянным состоянием и данными, уже присутствующими в кэше (обычно initialState).
  • если функция mergeState возвращает состояние, отличное от постоянного, состояние заменяется
  • если все прошло хорошо, регидратированному полю присвоено значение true, в противном случае выдается ошибка

Как StorageProxy восстанавливает постоянное состояние? Мы можем ответить на этот вопрос, проанализировав исходный код его функции восстановления, и мы можем увидеть, что данные восстанавливаются из хранилища, выполнив следующие действия:

  • извлекает все ключи, управляемые магазином, с помощью функции getAllKey
  • фильтрует ключи с помощью mutateKey
  • Функция хранилища multiGet используется для получения всех отфильтрованных значений ключей (хранилища, которые изначально реализуют multiGet, более эффективны, см. AsyncStorage, поддерживающий реакцию).
  • ключи и значения изменяются функциями mutate get
  • состояние создается с использованием измененных ключей и значений

Запись через функции, предоставляемые Cache

Как видно из кода кэша, функции записи выполняются в синхронном режиме для изменения состояния (поле data) и уведомления StorageProxy с помощью push функция измененного ключа.

Функция push StorageProxy выполняет четыре простых задачи:

  • мутация ключа и
  • убедитесь, что это ключ к сохранению
  • очередь внутренний ключ
  • выполняет функцию debounce

По истечении срока действия дебона (параметры кешированияthrottle: [Необязательно] [По умолчанию: 500]) выполняется функция выполнения и переходит к следующему:

  • удалить все повторяющиеся ключи из очереди, строка 3
  • сгруппировать все ключи, которые необходимо изменить и выполнить изменение значений, строка 32
  • group: все ключи будут удалены, строка 34
  • если есть ключи, которые нужно удалить, выполняется запрос multiRemove в хранилище (хранилища, которые изначально реализуют multiRemove, более эффективны, см. реакцию родной AsyncStorage), строки 39 и 40
  • если есть ключи, которые нужно изменить, выполняется запрос multiSet в хранилище (хранилища, которые изначально реализуют multiSet, более эффективны, см. реакцию родной AsyncStorage), строки 42 и 43

Выводы:

как кэш использует состояние и как он управляет обменом данными с хранилищем, обеспечивая высокую эффективность

Использование состояния как при записи, так и при чтении всегда происходит в синхронном режиме и с использованием внутреннего кеша.

Чтение данных из хранилища выполняется только один раз при запуске приложения и использовании функции multiGet.

Запись данных в хранилище поставлена ​​в очередь, устранена, дубликаты удалены, и только multiSet и multiRemove запросы делаются.

Что дальше

Если вы сопровождаете библиотеку управления состоянием и тоже хотели бы интегрировать i, я предлагаю вам прочитать сообщение о том, как я легко интегрировал его в apollo: Сохранение состояния в JavaScript - wora / cache-persist - Интеграция в кеш apollo

Как вы можете внести свой вклад

  • Если вы являетесь создателем библиотеки управления состоянием, рассмотрите возможность интеграции этой библиотеки.
  • Поставьте звезду репозиторию и поделитесь ею, вы поможете проекту и людям кому это пригодится
  • Создавайте проблемы, ваши вопросы станут ценным подспорьем
  • PR приветствуются, но всегда лучше сначала открыть проблему, чтобы помочь мне и другим людям, оценивающим ее