Indexedb 在 Chrome 中无法工作

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

我有以下代码。它在 Firefox 上完美运行,但在 Chrome 上不起作用。但如果我打开开发者工具,它甚至可以在 chrome 上运行。可能是什么问题?

function resetDatabase() {
            let request = indexedDB.deleteDatabase("CityDatabase4");

            request.onsuccess = function() {
                const cityVersion = 0; 
                localStorage.setItem('cityVersion', cityVersion);
                window.location.reload();
            };

            request.onerror = function() {
            };

            request.onblocked = function() {
            };
        }
google-chrome console indexeddb
1个回答
0
投票

该问题可能源于 IndexedDB 行为的两个关键方面

  1. 连接处理。根据规范,删除数据库时,必须首先关闭所有现有连接。如果在尝试删除数据库时其他连接仍然打开,则会触发

    onblocked
    事件。

  2. Chrome 的行为。 Chrome 可能会维护一些不立即可见的后台连接,这就是为什么打开 DevTools(可以强制连接清理)使其起作用。

这是代码的更正版本,它应该在浏览器中一致地工作:

function resetDatabase() {
    // First, close any existing connections
    const DBOpenRequest = indexedDB.open("CityDatabase4");
    DBOpenRequest.onsuccess = function(event) {
        const db = event.target.result;
        db.close();
        
        // Now proceed with deletion
        let request = indexedDB.deleteDatabase("CityDatabase4");

        request.onsuccess = function() {
            const cityVersion = 0; 
            localStorage.setItem('cityVersion', cityVersion);
            window.location.reload();
        };

        request.onerror = function(event) {
            console.error("Error deleting database:", event.target.error);
        };

        request.onblocked = function(event) {
            console.log("Database deletion blocked");
        };
    };
}
  1. 我们首先打开一个连接,以确保我们可以正确关闭任何现有连接
  2. 我们在尝试删除之前显式关闭数据库
  3. 添加了错误处理以帮助诊断问题
  4. 妥善处理
    onblocked
    事件

规格说明:

“如果 openConnections 中的任何连接仍未关闭,则将任务排队以根据请求使用数据库版本和 null 触发名为“blocked”的版本更改事件。”

*了解更多信息: https://w3c.github.io/IndexedDB/#opening

这就是为什么添加适当的连接清理有助于确保跨浏览器的一致行为。

其他建议:

  1. 添加超时处理:
function resetDatabase() {
    return new Promise((resolve, reject) => {
        const DBOpenRequest = indexedDB.open("CityDatabase4");
        const timeout = setTimeout(() => {
            reject(new Error("Database operation timed out"));
        }, 5000); // 5 second timeout

        DBOpenRequest.onsuccess = function(event) {
            const db = event.target.result;
            db.close();
            
            let request = indexedDB.deleteDatabase("CityDatabase4");

            request.onsuccess = function() {
                clearTimeout(timeout);
                const cityVersion = 0; 
                localStorage.setItem('cityVersion', cityVersion);
                resolve();
                window.location.reload();
            };

            request.onerror = function(event) {
                clearTimeout(timeout);
                reject(event.target.error);
            };

            request.onblocked = function(event) {
                clearTimeout(timeout);
                reject(new Error("Database deletion blocked"));
            };
        };

        DBOpenRequest.onerror = function(event) {
            clearTimeout(timeout);
            reject(event.target.error);
        };
    });
}
  1. 考虑添加
    versionchange
    事件侦听器来处理可能从另一个选项卡中删除数据库的情况:
db.onversionchange = function() {
    db.close();
};

这应该可以在不同的浏览器和场景中提供更可靠的行为。

© www.soinside.com 2019 - 2024. All rights reserved.