达到限制时的localStorage,限制和数据到期

时间:2013-11-18 19:20:18

标签: javascript

我尝试在localStorage中存储对象,但有时我的空间不足。

当我尝试存储具有localStorage但没有足够存储空间的对象时,是否可以根据需要删除尽可能多的本地数据以释放该空间,从最旧的元素开始删除?

浏览器中是否有API可以让我这样做?

3 个答案:

答案 0 :(得分:8)

这是我刚刚掀起的一个小概念证明。它假定当您尝试存储项目并且没有空间时会抛出异常。

代码注释

var Storage = function (iden) { // a storage wrapper object
    var storage; // temp storage with variable
    if (localStorage[iden]) { // if we already did this, reuse
        storage = JSON.parse(localStorage[iden]);
    } else {
        // the queue is for the item order to find out oldest
        storage = {
            __queue: [],
            items: {}
        };
    }

    function fetch(key) {
        console.log(storage);
        return storage.items[key];
    }

    function put(key, value) {
        try {
            storage.__queue.push(key);
            storage.items[key] = value;
            localStorage[iden] = JSON.stringify(storage);
        } catch (e) { // out of space
            if (storage.__queue.length === 0) throw Exception("Too big anyway");
            var k = storage.__queue.pop();
            delete storage.items[k];
            return put(key, value); //try again after deleting
        }
    }
    return {
        put: put,
        fetch: fetch
    };
};

答案 1 :(得分:5)

受@ Benjamin强大的概念证明的启发,我使用了他的一些代码来推出另一种解决方案,这个函数将删除最少使用的值。例如,你有一个像user_id这样的值,你很多次都会读到这个值,但是如果这个值被添加,那么当你的空间不足时就会失去它。

因此,此解决方案将根据使用的数量删除值

var Storage = function (iden) { // a storage wrapper object
    var storage; // temp storage with variable
    if (localStorage[iden]) { // if we already did this, reuse
        storage = JSON.parse(localStorage[iden]);
    } else {
        // frequency map contains which key was hit how many times.
        storage = {
            __freq: {},
            items: {}
        };
    }

    function fetch(key) {
        storage.__freq[key]++;
        return storage.items[key];
    }

    function deleteLeastUsed(){
        var min_used = '', min_value = 0;
        var keys = Object.keys(storage._freq);

        // This will be always the first key..awesome ?
        min_used = keys.pop();
        min_value = storage.__freq[min_used];

        keys.forEach(function(key){
            if( min_value > storage.__freq[key] ){
                min_used = key;
                min_value = storage.__freq[min_used];
            }
        });

        delete storage._freq[min_used]
        delete storage.items[min_used];
    }

    function put(key, value) {
        try {
            // sets frequency to 0 if the key is over-written
            // you can use this as `touch` if you don't wanna use a value more times and wan't to free it just set it to its value
            storage.__freq[key] = 0;
            storage.items[key] = value;
            localStorage[iden] = JSON.stringify(storage);
        } catch (e) { // out of space
            if ( Object.keys(storage.__freq).length === 0) 
                throw Exception("Too big anyway");
            deleteLeastUsed();
            return put(key, value); //try again after deleting
        }
    }
    return {
        put: put,
        fetch: fetch
    };
};

此外,如果您的数据要求非常高,您可能需要考虑切换到IndexedDB而不是localStorage。 : - )

答案 2 :(得分:1)

我在google中找到了这个:https://github.com/pamelafox/lscache是一个用于localstorage的“memcache”库