Pull to refresh

Comments 42

setTimeout конечно напрягает немного, а так все здорово конечно.
интервал нужно использовать с умом, ибо буут коллизии, если первая порция не успеет сохраниться а вторая начнет.
А вообще оба варианта напрягают, ибо за 5 секунд может очень многое случиться, а опера еще и не отлавливает анлоад.
Не забываем, что каждая запись в localStorage — физическое обращение к диску)
Так, жесткий диск Василия Пупкина был убит в износ неизвестным хакером из России…
Жесткий диск русского убит русским… Может Пупкин сам его и убил?
RubtsovAV подсказал, что можно сравнивать текущее значение хранилища и сериализованного объекта, а затем уже сохранять.
Устроим ад SSDшникам :)
Можно добавить проверку в _save перед сохранением на предмет: а были собсно изменения с последнего сохранения? В остальном оч интересное решение, нужно брать на вооружение. Спасибо!

Хоть экономия и копеешная, но всё же… :)
Нет нужды, кроме как при beforeunload. Если браузер закроется некорректно, данные уничтожатся.
Вообще да, логично! Чет я об этом не подумал…
Таймер не остановится если в коде потеряется ссылка на экземпляр ObjectStorage. Может вместо плоского типа сделать что-то вроде менеджера?
Подробнее, что вы имеете в виду?
function someTest() {
    // ...

    // Здесь в конструкторе ObjectStorage создался таймер -->
    var storage = new ObjectStorage("someStorage");
    
    
    // ...

    // Функция закончила своё действие, ссылка на storage 
    // потеряна, а таймер живёт, да и сборщик мусора объект
    // не убьет
}

function someTest2() {
    // ...

    // То же самое, что и в someTest
    var storage = new ObjectStorage("someStorage");

    // ...
}

someTest();
someTest2();


В итоге после вызова someTest и someTest2 будут крутится два потерянных таймера. И так каждый раз при создании экземпляра ObjectStorage.
Первое предложение я понял, а вот второе нет («Может вместо плоского типа сделать что-то вроде менеджера?»).

Какое решение этой проблемы вы предложите? Что-то типа синглтона?
Честно говоря, не вижу никакого смысла. В моём варианте человек может создать два экземпляра конструктора с разными именами и интервалами. Во-первых это позволит сохранять реже или чаще те или иные данные, в зависимости от «важности», во вторых не придется каждый раз сериализовывать всё, когда можно это делать по кускам.

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

А как быть с «убийством» интервала, когда ссылка не объект утеряна? Я вижу только один вариант: сделать какой-нибудь метод, который убивает интервал.
Чуть подредактировал, учитывая возможность очистки таймаута и создания лишь одного экземпляра с одним и тем же именем.
а this в функции callee ссылается на экземпляр класса или на саму функцию? может надежнее self заюзать?
Пардон, это опечатка.
Вот теперь хорошо. Можно как вариант у ObjectStorage сделать метод destroy, который уничтожает таймаут и убирает экземпляр из инстансов.
Используйте геттеры и сеттеры вместо таймаута
На осле не будет работать, а такой подход обладает массой преимуществ.
И недостатков тоже

На старом ослике вообще нету localStorage :). А на новом — вроде поддерживается. Если нет — определяйте и для него юзайте таймаут
Ну они действительно смотрятся неплохо :)
А в Opera Mobile setTimeout работает?

И кто-то «каждые несколько миллисекунд» — тестировал на большом объёме данных? Когда локал сторадж забит на все свои 5 Мб?
Насчет Timeout не скажу, а вот про «милисекунды» — сложно представить случай, когда нужно так часто сохранять данные. По мне интервал в 1-5 секунд самый оптимальный для таких задач.
При больших объемах можно отключать таймаут и делать сохранение, только в нужных местах. Можно добавить условие, что если duration === false, то таймер не запускать.
p.s. даже лучше вот так пожалуй if(duration > 0) setTimeout(....)
Без таймаута идея не особо-то и нужна — можно и «ручками» в local- и sessionStorage объект загнать
Да можно всё ручками :). С оберткой, то всё равно удобнее: есть задел на масштабируемость и разные фичи.
В принципе, гораздо проще так:
localStorage.setup = function(obj){
 for(var i in obj){
  if(Object.prototype.hasOwnProperty.call(obj, i))
   localStorage.setItem(i, obj[i]);
 }
}

А потом так:
localStorage.setup({ a:10, b:20 });

А если так:
localStorage.setup({ a:10, b:{c:[1,2,3,4],d:'error?'} });
Ок, тогда проще:
localStorage.setup = function(obj){
 localStorage.setItem('setupped', JSON.stringify(obj));
}
localStorage.get = function(obj){
 return JSON.parse(localStorage.setupped);
}
Цель данного — объяснить всем тем, кто добавил статью по ссылке в избранное или поставил плюсик, никогда не использовать этот код.

И где же собственно разоблачение?
Возможно ваш код лучше, но чем тот код аж так плох?
И тот и этот код — мой. Все плюсы по сравнению с тем подходом смотрите внизу.
Sign up to leave a comment.

Articles