javascript - 如何构建我的应用程序以在网站上运行时使用 localStorage,而在作为 Chrome 应用程序运行时使用 chrome.storage?

标签 javascript html google-chrome google-chrome-extension local-storage

我有a simple web我构建的应用程序使用 localStorage 将一组任务保存为字符串化的 JSON。它也是一个 Chrome extension在 Chrome 网上应用店上,并且代码库对于扩展程序和在 VPS 上运行的网站完全相同 http://supersimpletasks.com .

我想将我的扩展程序迁移到 Chrome App所以我可以访问 chrome.storage.sync API,它允许我的用户跨设备同步任务。如果我想存储超过 5mb 的数据,使用 chrome.storage 也会给我更多的灵 active 。

但是,当我的应用程序由 supersimpletasks.com 提供时,chrome.storage 将不起作用 - 我需要改用 localStorage。

据我了解,localStorage 是同步的而 chrome.storage 是异步的,这意味着需要大量重写如下方法。这两个方法负责从localStorage中获取任务和保存任务。

@getAllTasks: ->
  allTasks = localStorage.getItem(DB.db_key)
  allTasks = JSON.parse(allTasks) || Arrays.default_data

  allTasks

@setAllTasks: (allTasks) ->
  localStorage.setItem(DB.db_key, JSON.stringify(allTasks))
  Views.showTasks(allTasks)

如何构建我的应用程序以根据环境使用 localStorage 或 chrome.storage?我可能会遇到什么问题?

最佳答案

此问题的解决方案是创建您自己的存储 API。您已经确定 localStorage 是同步的,而 Chrome 存储是异步的,但这个问题很容易解决,只需将所有内容都视为异步即可。

创建您自己的 API,然后使用它代替所有其他调用。在您的代码中快速查找/替换可以用新 API 替换 localStorage 调用。

function LocalStorageAsync() {

     /**
      * Parses a boolean from a string, or the boolean if an actual boolean argument is passed in.
      *
      * @param {String|Boolean} bool A string representation of a boolean value
      * @return {Boolean} Returns a boolean value, if the string can be parsed as a bool.
      */
    function parseBool(bool) {
        if (typeof bool !== 'string' && typeof bool !== 'boolean')
            throw new Error('bool is not of type boolean or string');
        if (typeof bool == 'boolean') return bool;
        return bool === 'true' ? true : false;
    }

    /**
     * store the key value pair and fire the callback function.
     */
    this.setItem = function(key, value, callback) {
        if(chrome && chrome.storage) {
            chrome.storage.local.set({key: key, value: value}, callback);
        } else {
            var type = typeof value;
            var serializedValue = value;
            if(type === 'object') {
                serializedValue = JSON.stringify(value);
            }
            value = type + '::typeOf::' + serializedValue;
            window.localStorage.setItem(key, value);
            callback();
        }
    }

    /**
     * Get the item from storage and fire the callback.
     */
    this.getItem = function(key, callback) {
        if(chrome && chrome.storage) {
            chrome.storage.local.get(key, callback);
        } else {
            var stronglyTypedValue = window.localStorage.getItem(key);
            var type = stronglyTypedValue.split('::typeOf::')[0];
            var valueAsString = stronglyTypedValue.split('::typeOf::')[1];
            var value;
            if(type === 'object') {
                value = JSON.parse(valueAsString);
            } else if(type === 'boolean') {
                value = parseBool(valueAsString);
            } else if(type === 'number') {
                value = parseFloat(valueAsString);
            } else if(type === 'string') {
                value = valueAsString;
            }
            callback(value);
        }
    }
}


// usage example
l = new LocalStorageAsync();
l.setItem('test',[1,2,3], function() {console.log('test');});
l.getItem('test', function(e) { console.log(e);});

下面这个解决方案克服的一个问题是,除了将所有内容都视为异步之外,它还考虑了 localStorage 将所有内容转换为字符串这一事实。通过将类型信息保留为元数据,我们确保从 getItem 操作中得到的数据类型与进入的数据类型相同。

此外,使用工厂模式的一种变体,您可以创建两个具体的内部子类并根据环境返回适当的子类:

function LocalStorageAsync() {
    var private = {};

    private.LocalStorage = function() {
        function parseBool(bool) {
            if (typeof bool !== 'string' && typeof bool !== 'boolean')
                throw new Error('bool is not of type boolean or string');
            if (typeof bool == 'boolean') return bool;
                return bool === 'true' ? true : false;
        }
        this.setItem = function(key, value, callback) { /* localStorage impl... */ };
        this.getItem = function(key, callback) { /* ... */ };
    };

    private.ChromeStorage = function() {
        this.setItem = function(key, value, callback) { /* chrome.storage impl... */ };
        this.getItem = function(key, callback) { /* ... */ };
    }

    if(chrome && chrome.storage)
        return new private.ChromeStorage();
    else
        return new private.LocalStorage();
};

关于javascript - 如何构建我的应用程序以在网站上运行时使用 localStorage,而在作为 Chrome 应用程序运行时使用 chrome.storage?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26249133/

相关文章:

selenium - 哪个 ChromeDriver 版本与哪个 Chrome 浏览器版本兼容?

javascript - iframe 内的脚本不工作

html - Internet Explorer 错误边距,其他都不错

html - 仅使用 css 在悬停时更改段落

javascript Canvas : chrome touch screen not working

ajax - --disable-web-security 在 Chrome 中还能用吗?

javascript - 如何获取任何 Android 手机的 MAC 地址?

javascript - Chartjs 无边框条形图

JavaScript "Static Object"或库

javascript - 在 Summernote 中使用 <br> 而不是 <p>?