говорить сlocalStorage
Предположительно знакомые с фронтендом друзья не будут незнакомы, можем воспользоваться предоставленнымgetItem
, setItem
, removeItem
, clear
эти несколькоAPI
Легко «читать, писать, удалять» данные, хранящиеся локально в браузереоперации, но по сравнению сcookie
, localStorage
Единственная ложка дегтя это«Невозможно установить срок действия каждого ключа»**.
❝
Свойство localStorage позволяет нам получить доступ к объекту Хранилище происхождения документа; сохраненные данные будут храниться в сеансе браузера. localStorage похож на sessionStorage, но разница в том, что данные, хранящиеся в localStorage, могут храниться длительное время, а при завершении сеанса страницы, то есть при закрытии страницы, данные, хранящиеся в sessionStorage, будут очищены.
❞
Мы также должны отметить, чтоlocalStorage
Пары ключ-значение всегда хранятся в виде строк.
описание проблемы
В сценариях практического применения нам часто нужно сделатьlocalStorage
множество"ключ"Он может автоматически выйти из строя в течение заданного времени, поэтому, исходя из этого сценария, как мы можем решить эту проблему?
1. Основное решение
Для друзей, которые только знакомятся с фронтендом, ответ можно дать сразу:
localStorage.setItem('dooring', '1.0.0')
// 设置一小时的有效期
const expire = 1000 * 60 * 60;
setTimeout(() => {
localStorage.setItem('dooring', '')
}, expire)
Конечно, это решение может решить временную проблему, но если вы хотите установить срок действия любого ключа, вам нужно написать несколько таймеров для использования этого решения.«Стоимость обслуживания чрезвычайно высока, и это не способствует повторному использованию техники».
2. Промежуточный раствор
После того, как front-end инженеры имеют определенный опыт работы, они часто рассматривают вопросы проектирования и повторного использования, и имеют определенное понимание структуры данных, поэтому могут быть следующие решения:
- Используйте **"localStorage"**, чтобы сохранить таблицу сопоставления {key(key): expire(время истечения срока действия)}
- Перепишите **"localStorage API"**, дважды инкапсулируйте метод
Аналогичный код выглядит следующим образом:
const store = {
// 存储过期时间映射
setExpireMap: (key, expire) => {
const expireMap = localStorage.getItem('EXPIRE_MAP') || "{}"
localStorage.setItem(
'EXPIRE_MAP',
JSON.stringify({
...JSON.parse(expireMap),
key: expire
}))
},
setItem: (key, value, expire) => {
store.setExpireMap(key, expire)
localStorage.setItem(key, value)
},
getItem: (key) => {
// 在取值之前先判断是否过期
const expireMap = JSON.parse(
localStorage.getItem('EXPIRE_MAP') || "{}"
)
if(expireMap[key] && expireMap[key] < Date.now()) {
return localStorage.getItem(key)
}else {
localStorage.removeItem(key)
return null
}
}
// ...
}
В мгновение ока это решение решает проблему повторного использования и может использоваться разными командами, но все же есть некоторые недостатки:
- правильно
store
2 копии данных должны поддерживаться во время работы и занимают место в кэше - если
EXPIRE_MAP
Случайное удаление аннулирует все сроки действия - Отсутствие более гибкого управления процессом операции (такой как статус операции, обратный вызов операции и т.д.)
3. Передовые решения
Что мы должны сделать, чтобы снизить затраты на обслуживание и занимаемое пространство, а также обеспечить определенную степень гибкости управления и отказоустойчивости?
Здесь я думаю о двух похожих решениях:
- сохранить время истечения срока действия, чтобы
key
, например dooring|6000, используйте разделитель "|" для разделения каждого значенияkey
а такжеexpire
вывести, судить - сохранить время истечения срока действия, чтобы
value
, например 1.0.0|6000, остальные такие же, как 1
Для большей инкапсуляции и надежности мы также можем настроить обратные вызовы в разных состояниях, которые просто реализованы следующим образом:
const store = {
preId: 'xi-',
timeSign: '|-door-|',
status: {
SUCCESS: 0,
FAILURE: 1,
OVERFLOW: 2,
TIMEOUT: 3,
},
storage: localStorage || window.localStorage,
getKey: function (key: string) {
return this.preId + key;
},
set: function (
key: string,
value: string | number,
time?: Date & number,
cb?: (status: number, key: string, value: string | number) => void,
) {
let _status = this.status.SUCCESS,
_key = this.getKey(key),
_time;
// 设置失效时间,未设置时间默认为一个月
try {
_time = time
? new Date(time).getTime() || time.getTime()
: new Date().getTime() + 1000 * 60 * 60 * 24 * 31;
} catch (e) {
_time = new Date().getTime() + 1000 * 60 * 60 * 24 * 31;
}
try {
this.storage.setItem(_key, _time + this.timeSign + value);
} catch (e) {
_status = this.status.OVERFLOW;
}
cb && cb.call(this, _status, _key, value);
},
get: function (
key: string,
cb?: (status: number, value: string | number | null) => void,
) {
let status = this.status.SUCCESS,
_key = this.getKey(key),
value = null,
timeSignLen = this.timeSign.length,
that = this,
index,
time,
result;
try {
value = that.storage.getItem(_key);
} catch (e) {
result = {
status: that.status.FAILURE,
value: null,
};
cb && cb.call(this, result.status, result.value);
return result;
}
if (value) {
index = value.indexOf(that.timeSign);
time = +value.slice(0, index);
if (time > new Date().getTime() || time == 0) {
value = value.slice(index + timeSignLen);
} else {
(value = null), (status = that.status.TIMEOUT);
that.remove(_key);
}
} else {
status = that.status.FAILURE;
}
result = {
status: status,
value: value,
};
cb && cb.call(this, result.status, result.value);
return result;
},
// ...
};
export default store;
Таким образом, мы достигли каждогоkey
Каждый из них имеет независимое время истечения срока действия и может легко контролировать статус различных результатов операции ~
4. Зольный раствор
Конечно, раствор золы использовать непосредственноxijs
этоjavascript
Библиотека инструментов, поскольку я инкапсулировал приведенную выше полную схему реализации в эту библиотеку, нам нужно использовать только следующую схему, чтобы легко использовать мощные инструменты со сроком действия."локальное хранилище"метод:
// 先安装 yarn add xijs
import { store } from 'xijs';
// 设置带有过期时间的key
store.set('name', 'dooring', Date.now() + 1000);
console.log(store.get('name'));
setTimeout(() => {
console.log(store.get('name'));
}, 1000);
// 设置成功后的回调
store.set('dooring', 'xuxiaoxi', Date.now() + 1000, (status, key, value) => {
console.log('success');
});
в то же времяxijs
Мы продолжаем расширять полезные функции инструментов, чтобы сделать развитие бизнеса более эффективным.Мы интегрировали следующие функции инструментов:
-
"хранить"на основе
localStorage
Библиотека инкапсулированного кэша верхнего уровня, которая поддерживает настройку времени истечения срока действия и поддерживает обратные вызовы операций. - "УУИД"Генерирует уникальный идентификатор, длина поддержки предоставлена
- "randomStr"Генерировать указанное количество случайных строк
- "форматДата"Готовые инструменты форматирования времени
- "развенчать"Функция защиты от сотрясений
- "Дроссель"Функция дроссельной заслонки
- "url2obj"Преобразование строки URL в объект
- "obj2url"Преобразование объекта в закодированную строку URL
- "исПК"Определите, является ли устройство типом ПК
адрес гитхаба:GitHub.com/Mr X U соус/Маленький…
Адрес документа:h5.dooring.cn/xijs
Если вы найдете это полезным, не забудьте поставить звездочку~
больше рекомендаций
- Как быстро разработать страницы H5 со строительными блоками?
- Разработайте библиотеку анимации загрузки на основе React с нуля
- Разработайте легкий плагин кода проверки скольжения от нуля
- Как спроектировать хранилище компонентов для платформы визуального построения?
- Проектирование механизма визуализации большого экрана с нуля
- Используйте электрон для создания настольного визуального редактора Dooring с нуля
- (Low Code) Платформа визуализации Анализ дизайна источника данных
- Создайте редактор страниц для ПК PC-Dooring с нуля