Работа с локальным хранилищем, как с объектом
http://habrahabr.ru/post/143597/
Выношу на обсуждение своё небольшое изобретение для тех, кого нет на хабре и для тех, кого харит там комментировать. Здесь хотя-бы можно нормально обосрать, не боясь слива. |
Из за наличия таймера с таким объектом нужно работать специфически например насколько я понимаю его в цикл нельзя вставить
|
Цитата:
|
А хотя, чего бы нет? Взять объект, поработать с ним в цикле, а затем, после всех операций, присвоить.
|
мда, вариант интересный но не годный, например такой способ не вызовет геттер и вся твоя реализация идет прахом:
objectLocalStorage = { a: 4, b: {c: 2} };
var b = objectLocalStorage.b;
b.c = 10;
alert( objectLocalStorage.b.c ); // alert 2
Я делал что-то подобное, но отказался от этого решения из-за этого недостатка. |
devote, угу, я внизу указал на это. Думаю, решение найти можно, но оно будет очень тяжелым. То есть для каждого ключа каждого подобъекта добавить геттер и хранить это всё как-нибудь.
С другой стороны, с этим объектом можно поработать, а затем присвоить туда, откуда взял. Всё же некоторая оптимизация. |
Идея — говно :D
Цитата:
|
Цитата:
if(timer == null) {
timer = setTimeout( function(){
var stringified = JSON.stringify( _objectLocalStorage );
// некое подобие оптимизации: если данные в объекте не изменились,
// значит присваивания никакого не было, сработал обычный гет
if( stringified !== localStorage.getItem( 'objectStorage' ) ) {
// сохраняем
localStorage.setItem( 'objectStorage', stringified );
}
timer = null;
}, 0);
}
|
Цитата:
|
Цитата:
не? |
Цитата:
|
Цитата:
|
var Storage = function Storage ( name, duration ) {
this._name = name || this._name;
this._duration = duration || this._duration;
this._init();
}
Storage.prototype = {
_name: '_nameOfYourSrorage',
_duration: 5000,
// type == local || session
_save: function( type ) {
window[ type + 'Storage' ].setItem( this._name, JSON.stringify( this[ type ] ) );
},
_get: function( type ) {
this[ type ] = JSON.parse( window[ type + 'Storage' ].getItem( this._name ) ) || {};
},
_init: function() {
var self = this;
self._get( 'local' );
self._get( 'session' );
( function callee() {
setTimeout( function() {
self._save( 'local' );
callee();
}, self._duration );
})();
window.addEventListener( 'beforeunload', function() {
self._save( 'local' );
self._save( 'session' );
} );
},
local: {},
session: {}
};
Вот самый адекватный и производительный вариант использования хранилища, как объекта. Взял из своего проекта, может быть кому-то будет полезным.
var storage = new Storage;
storage.local = {a:4, b: {c:5}};
storage.session = {a:7, b: {c:8}};
b = storage.local.b;
b.c = {d:6};
Стоит объяснять что к чему? |
FINoM,
Гениально! Просто, удобно (никакой асинхронности). Спасибо:thanks: |
FINoM, видел ваш пост на хабре.
жаль, что вы про IE забыли :( там ведь чуточку сложнее, и все по-другому. но использование одинаковое. |
Цитата:
А этот вариант на хабре предложили, моя заслуга здесь только в нескольких строках кода. |
Цитата:
|
Цитата:
|
Цитата:
objectLocalStorage.a ← вызовет эту сложную операцию. Кроме этого, objectLocalStorage.a.b = 5; // сработает a = objectLocalStorage.a; a.b = 5; // не сработает |
|
Цитата:
|
Шота меня setTimeout дюже смущает, в виду возможности вселенских масштабов утечек связанных с ним.
|
Цитата:
|
Цитата:
|
Цитата:
|
Deff, стараюсь не пользоваться, потому и не проверял.
|
GuardCat,
У мну подозрение - что - поменее, а использование таково: - засылать периодически запросы на сервак - нет ли новых данных - (Была задачка в компутерном киоске на улице |
Deff, может проще тогда в callback запроса вставить следующий запрос по setTimeout? Тогда и ошибку можно обработать и не получится такого, что запрос пытаемся повторить до того, как пришёл ответ на предыдущий? Гибче setTimeout.
|
GuardCat,
браузеры при использовании чего либо отъедают память и тестить смотря в диспетчер задач нет смысла. Так как там всегда разные цифры, никогда не бывают одни и те же. |
Цитата:
|
Цитата:
|
Цитата:
Я привести тест(визуализация действий пользователя в админке) не могу, слишком сложно его воспроизводить, но у меня первая упала Опера 12, затем Firefox12 и затем Chrome 7-19 из-за того что setTimeout сожрал всю память. Твой тест не сильно поможет при создании сложного приложения, которое работает больше 20 минут. Я такие тесты вообще перестал делать. Тестирую часами, по 8 - 12 часов. К сожалению не знаю как сделать это по другому, но возможно, что никто не знает. |
GuardCat,
Ну у мну запрос отправлялся раз в час, быстрее данные не обновлялись, ксать как то работало с неделю без перезагрузки.. Хотя я рекомендовал раз в день, Да браузер был Гугол Хром |
Gozar, да, я понимаю, что запускать новый gmail, руководствуясь моим опытом, не стоит =)
Опыт с 8--12 часами работы приложения можно приблизить к реальности, наняв гастарбайтера и предложив ему понажимать всё подряд на экране в течение этого времени =) |
Цитата:
|
Gozar, говоря "мой опыт", я подразумеваю опыт в смысле "эксперимент". Я про это своё исследование setTimeout.
Да и js в данный момент для меня просто хобби, а не область профессиональных интересов. |
Deff, вот поэтому я избегаю использовать setInterval, предпочитая многократный setTimeout.
|
Цитата:
Я говорил немного о другом. Скорее о том, что при использовании долгоиграющих функций и setTimeout входит в их число очень легко наступить на грабли, даже не подозревая об этом. Ух ты у меня карма 166. Похоже сегодня Пятница 13 по Чучхенскому календарю. :blink: |
Прелесть использования setTimeout ещё и в том, что время задержки можно корректировать при каждом следующем запуске функции, в зависимости от того, на сколько задержался предыдущий таймер.
Суммарное время таймеров при этом будет правильным настолько, насколько это вообще возможно в браузере. Это хорошо видно при анимации: если произошел лаг (а это частое явление) - следующий шаг будет уже больше, уменьшая время, оставшееся до конца анимации. И это правильно. |
Цитата:
clearInterval, и перезапуск, и У мну жуткое подозрение что setTimeout и setInterval формируются одинаково, ток у setTimeout стоит однократный флаг исполнения завершающий функцию, очевидно, еще и чистит дефолтное или установленное Timerid |
| Часовой пояс GMT +3, время: 15:33. |