如何在 javascript 中正确处理 indexeddb api 中的错误?

问题描述 投票:0回答:1

在javascript中,我这里有一个类来处理请求。我想确保所有的错误处理都设置好了。我想打开与数据库的连接并在每次请求时关闭它。到目前为止我有这个代码

export default class IndexedDBStorage {

    #name:string;

    constructor(name:string) {
        this.#name = name;
    }

    private async GetDB():Promise<IDBDatabase> {
        return new Promise((resolve, reject) => {

            // https://javascript.info/indexeddb
            const request = window.indexedDB.open(this.#name, 1);

            request.onupgradeneeded = () => {
                //this.#db = request.result;
                if (!request.result.objectStoreNames.contains(this.#name)) {
                    request.result.createObjectStore(this.#name, {keyPath: 'id', autoIncrement:true});
                }
            };

            request.onerror = () => {
                reject("Why didn't you allow my web app to use IndexedDB?! " + request.error?.code);
            };

            request.onsuccess = () => {
                //request.result.onerror = () => {
                    // Generic error handler for all errors targeted at this database's requests!
                //    reject("Database error: " + request.error?.code);
                //};

                resolve(request.result);
            };
        });
    }

    async GetAllItems<T>():Promise<Array<T>> {
        return new Promise((resolve, reject) => {
            this.GetDB().then(db => {
                const transaction = db.transaction(this.#name);
                const store = transaction.objectStore(this.#name);
                const datarequest = store.getAll();
                db.close();
                datarequest.onsuccess = function() {
                    resolve(datarequest.result);
                };
                datarequest.onerror = function() {
                    reject("Error " + datarequest.error);
                }; 
            }).catch(err => {
                console.error(err);
            });
        });
    }
}

还想知道,

GetDB
函数里面这部分有什么区别。这是数据库本身的 onerror 事件,它是在 onsuccess 事件中设置的。

            //request.result.onerror = () => {
                // Generic error handler for all errors targeted at this database's requests!
            //    reject("Database error: " + request.error?.code);
            //};

还有这部分

            datarequest.onerror = function() {
                reject("Error " + datarequest.error);
            }; 

?

谢谢

javascript html indexeddb
1个回答
0
投票
  • 请求可能会出错,当请求出错时,它会获取具有值
    error
  • 属性
  • 交易可能会出错,但错误只能从交易中出错的请求之一访问
  • 打开数据库的请求和get/put/add/etc的请求没有太大区别。从技术上讲,一种是 IDBOpenRequest 类型,一种是 IDBRequest 类型,我认为 IDBOpenRequest 扩展了 IDBRequest
  • 如果处理事务错误,通过事件访问错误,因为 event.target 将指向出错的请求,所以 event.target.error,又名 request.error,是错误对象,而 event 只是事件而不是错误本身
  • 你可以将 IDBOpenRequest 包装在一个承诺中,你可以将一个请求或交易包装在一个承诺中
  • 通常避免在 promise 中包装请求,除了打开的请求,始终包装外部事务,因为 promise 微任务可能存在问题以及 indexeddb 事务如何在事件循环中超时
  • 因为您在 GetAllItems 中捕获了 promise 拒绝,并且您用于捕获的回调是一个 void 函数,所以您有效地抑制了错误并返回一个始终解析为数组或未定义的 promise
  • 你没有考虑在开放请求中可能发生的阻塞事件,基本上承诺无限期地未解决(直到数据库被解锁,因为并发版本更改事务完成),所以这段代码并不总是能很好地工作
  • 我建议不要监听冒泡到数据库的错误,总是在请求级别监听错误(除了在承诺中包装事务时,在这种情况下在事务级别监听但通过 event.target.error 访问错误,它指向错误的事务中的请求),我强烈建议完全忽略 indexeddb 的冒泡功能
© www.soinside.com 2019 - 2024. All rights reserved.