IndexedDB主线程& WebWorker eventlisteners

时间:2016-01-10 14:29:07

标签: javascript indexeddb web-worker

您好我正在构建一个使用indexeDB的应用程序。基于app config,我可以选择是否应该使用来自WebWorker的indexeDB或主UI线程。无论配置如何,始终都会与主UI线程建立连接。但是,根据配置,如果选择了工作人员,则会进行繁重的工作。

导入原型示例:

Database.prototype.importItem = function(item, callback) {

    if (this.settings.useWorker) {

        this.postMessage({
            cmd: "importItem",
            data: item
        }, callback);

    } else {

        var that = this;
        var transaction = this.db.transaction(this.settings.collection, "readwrite");
        var objectStore = transaction.objectStore(this.settings.collection);
        var request = objectStore.add(item);

        request.onerror = function(evt) {
            if (callback && callback instanceof Function) {
                callback(new ApplicationError("importItem error", evt.target.error), null);
            }
        };

        request.onsuccess = function(evt) {
            if (callback && callback instanceof Function) {
                callback(null, evt.target.result);
            }
        };

        transaction.oncomplete = function(evt) {};

    }
};

我对于思想的好奇是indexedDB所需的事件监听器,例如:

Database.prototype.connect = function() {

    if (!this.supported()) {
        return this.emit("error", new ApplicationError("IndexedDB not supported!"));
    }

    var that = this;
    var openRequest = window.indexedDB.open(this.settings.dbName, this.settings.dbVersion);

    /**
     * [onerror description]
     * @param  {[type]} evt [description]
     * @return {[type]}     [description]
     */
    openRequest.onerror = function(evt) {
        that.emit("error", new ApplicationError("openRequest.onerror error", evt.target.error));
    };

    /**
     * [onblocked description]
     * @param  {[type]} evt [description]
     * @return {[type]}     [description]
     */
    openRequest.onblocked = function(evt) {
        // If some other tab is loaded with the database, then it needs to be closed
        // before we can proceed.
        alert("Please close all other tabs with this site open!");
    };

    /**
     * [onsuccess description]
     * @param  {[type]} evt [description]
     * @return {[type]}     [description]
     */
    openRequest.onsuccess = function(evt) {

        that.db = evt.target.result;

        that.db.onerror = function(evt) {
            logger.warn("openRequest.onsuccess error", evt.target);
        };

        that.db.onabort = function(evt) {
            logger.warn("openRequest.onsuccess abort", evt.target);
        };

        that.db.onversionchange = function(evt) {
            that.db.close();
            that.emit("versionchange", new ApplicationError("openRequest.onsuccess version change", evt.target));
        };

        if (that.settings.useWorker) {
            that.requestWorker();
        } else {
            that.emit("connect");
        }

    };

    /**
     * [onupgradeneeded description]
     * @param  {[type]} evt [description]
     * @return {[type]}     [description]
     */
    openRequest.onupgradeneeded = function(evt) {

        var stores = {};

        that.db = evt.target.result;

        that.db.onerror = function(evt) {
            logger.warn("openRequest.onupgradeneeded error", evt.target);
        };

        that.db.onabort = function(evt) {
            logger.warn("openRequest.onupgradeneeded abort", evt.target);
        };

        that.db.onversionchange = function(evt) {
            that.db.close();
            that.emit("versionchange", new ApplicationError("openRequest.onupgradeneeded version change", evt.target));
        };

        // Check for the objectStore - collection and delete it if exists
        if (that.db.objectStoreNames.contains(that.settings.collection)) {
            that.db.deleteObjectStore(that.settings.collection);
        }

        // Create new objectStore
        stores[that.settings.collection] = that.db.createObjectStore(that.settings.collection, {
            keyPath: that.settings.indexes[0]
        });

        // Create database indexes
        that.settings.indexes.forEach(function(index) {
            stores[that.settings.collection].createIndex(index, index, {
                unique: false
            });
        });

        that.upgraded = true;
        that.emit("upgrade");

    };

    /**
     * [onbeforeunload description]
     * @param  {[type]} evt [description]
     * @return {[type]}     [description]
     */
    window.onbeforeunload = function(evt) {
        that.db.close();
    };

};

由于我总是首先从主ui然后从工作者连接,我应该只在主UI线程中而不是在工作者中监听诸如“onblocked,versionchange”之类的事件吗?我假设不需要从两个线程中听取它?

更新

我知道这是一个奇怪的实现,但我之所以考虑这个原因是因为我正在一台拥有3GB ram和2个内核的机器上构建一个应用程序...我还有一个迭代所有方法的方法来自我的数据库的集合中的记录。我在想的是将检索到的每个记录传递给另一个图像加载方法&操作然后可能调用回调...这将限制内存使用,因为如果我没有弄错的话,它会在系列中完成。但是我不确定交易是否仍然有效。

底线这是我考虑2个连接的主要原因(因为1个方法),我想知道我是否可以避免双事件监听器。也许在1个帖子中有一些。

1 个答案:

答案 0 :(得分:1)

你做错了。不应在两个线程上打开IndexedDB连接。它使您的应用程序架构不必要地复杂化。从IndexedDB检索的数据可以通过Web workers' messaging channel与UI线程轻松交换。