【问题标题】:Correct way to add multiple objects in indexedDb?在 indexedDb 中添加多个对象的正确方法?
【发布时间】:2019-01-14 06:36:57
【问题描述】:

我有以下要添加到 indexedDb 的对象数组:

const data = [
    { name: 'abc',
      color: 'blue'
    },
    { name: 'xyz',
      color: 'red'
    },
    { name: 'yui',
      color: 'black'
    }];

现在我创建数据库并将这些数据插入到这样的存储中:

if (!db.objectStoreNames.contains("people")) {
        peopleStore = db.createObjectStore("people", { keyPath: "name" });
        peopleStore.createIndex("color", "color", { unique: false });

        peopleStore.transaction.oncomplete = function(event) {
            data.forEach(function(data) {
                operations.add(data);
            });
        };
    }

我已经使用add()(在const operations 内部)方法定义了一个函数表达式,如下所示:

add: function(data) {
            let request = db
                .transaction(["people"], "readwrite")
                .objectStore("people")
                .add(data);
        }

以下是我的问题:

  1. 这样是不是每次add()方法都会创建一个新事务 是被调用还是在单个事务中插入所有数据?

  2. 如果每次都创建一个新事务,我怎么才能只做 1个事务来提高性能并执行所有操作 它只是。我猜我必须创建一个全局变量 事务并对其执行操作(还有其他方法,如edit()delete() 等,每个方法内部都有一个“request”变量,用于定义一个事务,类似于我所展示的多于)。 我应该像这样创建一个全局变量:

const globalTrans = db.transaction(["people"], "readwrite").objectStore("people");

  1. 创建新事务是一项昂贵的操作吗?

提前感谢所有花时间回复的人! :)

【问题讨论】:

    标签: javascript html indexeddb


    【解决方案1】:

    创建全局变量会产生问题。可能是事务正在运行,而对于另一个操作,您可能会覆盖它。

    例如-

    var globalTx;
    // let's say you are selecting data from people
    globalTx = db.transaction(["people"], "read")  // in read access
    // and at same time you are inserting data from employee
    globalTx = db.transaction(["employee"], "readwrite") // in read write
    

    有很多方法可以解决这个问题-

    1. 根据场景创建多种方法-
    // for single value
    function add(data) {
        let request = db.transaction(["people"], "readwrite").objectStore("people").add(data);
    }
    
    // for multiple value
    function addMultiple(datas, callback) {
        const tx = db.transaction(["people"], "readwrite");
    
        datas.forEach(data => {
            let request = tx.objectStore("people").add(data);
        })
    
        tx.oncomplete = function(event) {
            callback();
        }
    };
    
    1. 修改函数只接收数组值-
    // so now data will be only array    
    function add(datas, callback) {
        const tx = db.transaction(["people"], "readwrite");
    
        datas.forEach(data => {
            let request = tx.objectStore("people").add(data);
        })
    
        tx.oncomplete = function(event) {
            callback();
        }
    };
    
    // so when want to insert single value , we will call like this.
    
    const value = {
        id: 1,
        name: 'ujjwal'
    }
    add([value], () => {
    
    })
    

    希望这能回答你的问题。

    【讨论】:

    • 请注意...在您的function addMultiple(data, callback) 这一行中let request = tx.objectStore("people").add(data); 应为let request = tx.objectStore("people").add(value);。注意“价值”的变化
    • 啊哈,谢谢你的指出。已更新代码。
    • indexedDB 如何知道何时提交事务?什么时候打电话给tx.complete
    • 所以我不必检查单个插入操作是否有错误,我只需要在事务级别检查它吗?而如果一次插入失败,整个事务会回滚吗?
    • 您还可以在每次插入时捕获错误,或者您可以查看整个事务。 Indexeddb 是事务性数据库,因此如果其中一个 tx 失败,则整个 tx 将被中止。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 2021-02-12
    • 2011-06-02
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多