Wpadłem na to dzisiaj podczas testowania (przekraczając limit miejsca) i przygotowałem rozwiązanie. IMO, wiedząc, jaki jest limit i gdzie jesteśmy w stosunku, jest znacznie mniej wartościowe niż wdrożenie funkcjonalnego sposobu na dalsze przechowywanie poza limitem.
Dlatego zamiast próbować porównywać rozmiary i sprawdzać pojemność, reagujmy, gdy osiągniemy limit, zmniejszamy naszą obecną pamięć o jedną trzecią i wznawiamy przechowywanie. Jeśli wspomniana redukcja się nie powiedzie, przestań przechowywać.
set: function( param, val ) {
try{
localStorage.setItem( param, typeof value == 'object' ? JSON.stringify(value) : value )
localStorage.setItem( 'lastStore', new Date().getTime() )
}
catch(e){
if( e.code === 22 ){
console.log('Local storage capacity reached.')
var maxLength = localStorage.length
, reduceBy = ~~(maxLength / 3);
for( var i = 0; i < reduceBy; i++ ){
if( localStorage.key(0) ){
localStorage.removeItem( localStorage.key(0) );
}
else break;
}
if( localStorage.length < maxLength ){
console.log('Cache data reduced to fit new entries. (' + maxLength + ' => ' + localStorage.length + ')');
public.set( param, value );
}
else {
console.log('Could not reduce cache size. Removing session cache setting from this instance.');
public.set = function(){}
}
}
}
}
Ta funkcja znajduje się w obiekcie opakowującym, więc public.set po prostu wywołuje samą siebie. Teraz możemy dodać miejsce do przechowywania i nie martwić się, jaki jest przydział ani jak blisko jesteśmy. Jeśli pojedynczy sklep przekracza 1/3, wielkość przydziału to miejsce, w którym ta funkcja przestanie wybierać i zakończy przechowywanie, a w tym momencie nie powinieneś i tak buforować, prawda?