【问题标题】:IDBDatabase Transaction Error not being handled未处理 IDBDatabase 事务错误
【发布时间】:2021-02-17 13:43:28
【问题描述】:

我正在尝试构建一个通用的 IndexedDB 模块以在多个项目中使用。我遇到了一些我无法弄清楚的奇怪行为。

据我了解,事务只能发生 3 个事件,但是,当我故意应用错误的 objectStore 时,不会执行中止或错误事件。

如果这是我设置不正确或者这是预期的行为,我很困惑,感谢您花时间查看我的问题!

/**
 * Adds a single object to the specificed objectStore
 * @param {IDBDatabase} database Initiliazed database
 * @param {string} objectStore Name of objectStore where transactions will be occurring
 * @param {object} data Object to be inserted into the objectStore
 * @returns {Promise} Resolve => String | Reject => Error
 */
async function addRecord(database, storeName, data) {
    return new Promise(function (resolve, reject) {
        try {
            let transaction = database.transaction(storeName, "readwrite");

            transaction.oncomplete = function () {
                console.log("Add Transaction Successful.");
            };

            transaction.onabort = function (event) {
                throw (`Transaction Aborted - Supplied Data {${database},${storeName},${data}} Code: ${event.target.errorCode} Error: ${request.error}`)
            }

            transaction.onerror = function (event) {
                throw (`Transaction Failed - Supplied Data {${database},${storeName},${data}} Code: ${event.target.errorCode} Error: ${request.error}`)
            };

            let objectStore = transaction.objectStore(storeName);

            let request = objectStore.add(data);

            request.onsuccess = function () {
                console.log("Add Request Succesful");
                resolve()
            };

            request.onerror = function (event) {
                console.log(`Request Failed: addRecord - Supplied Data {${database_name},${database_version},${upgrade_function}} Code: ${event.target.errorCode} Error: ${request.error}`)
                throw (`Request Failed: Supplied Data {${database_name},${database_version},${upgrade_function}} Code: ${event.target.errorCode} Error: ${request.error}`)
            };

        } catch (error) {
            reject(`Error: AddRecord - ${error.message}`)
        }
    });
}

【问题讨论】:

    标签: javascript web-deployment indexeddb


    【解决方案1】:
    1. 在事务完成时解决承诺,而不是在请求完成时。
    2. 事务错误时拒绝,而不是请求错误时拒绝。基本上摆脱您的 onsuccess/onerror 请求,或者仅将它们用于登录控制台而不是其他任何东西。
    3. 不要使用 try catch,catch 不会总是捕捉到你期望的错误,它基本上是没有意义的
    4. 不要使用 async 限定符,你没有在等待任何东西,这是没有意义的
    5. 你真的应该退后一步去学习异步编程,这是你沮丧的根源,但这不是一个简单的回答,有时需要100页的书才能解释它

    根据您的评论,试试这个:

    function connect(name, version, onupgradeneeded) {
      return new Promise((resolve, reject) => {
        const request = indexedDB.open(name, version);
        request.onsuccess = event => resolve(request.result);
        request.onerror = event => reject(request.error);
        request.onupgradeneeded = onupgradeneeded;
      });
    }
    
    function addRecord(database, storeName, data) {
      return new Promise((resolve, reject) => {
        const transaction = database.transaction(storeName, "readwrite");
        transaction.oncomplete = resolve;
        transaction.onerror = event => reject(event.target.error);
        transaction.objectStore(storeName).add(data);
      });
    }
    
    async function main() {
      const db = await connect('mydb', 1);
      console.log('connected');
      try {
        await addRecord(db, 'things', { foo: 'bar' });
        console.log('added record');
      } catch (error) {
        console.log(error);
      }
    }
    

    【讨论】:

    • 对不起,忽略上面的评论,错过了我的 shift 键 3 -> 你有替代品的推荐吗?我的想法是使用它作为将所有错误包装成特定格式的一种方式,以便通过详细调试来拒绝。这可能只是不好的做法,这是我想到的第一个方法。 4 -> IndexedDB 是一个异步 API,所以我认为将它们标记为异步并返回一个承诺是有意义的,这样我就可以解决它,以便我可以提取数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多