javascript - 全局变量只能由第一个函数访问?

标签 javascript indexeddb

我对 JS 有一定的了解,但最终仍在学习中。我正在尝试重新创建一个 PHP/mySQL 项目到 IndexedDB,但无法弄清楚为什么我在这里看到错误。

IndexedDB 连接按预期工作。第一个函数 (createItem) 运行良好,但第二个函数 (getItems) 返回错误,声称“db”变量未定义。它是一个全局变量,因此应该可以通过函数的作用域访问,并且 createItem 函数使用它没有问题。谁能帮我看看我在这里错过了什么。

// GLOBAL DB VAR
var db;
// WAIT FOR DOM
document.addEventListener("DOMContentLoaded", function(){
    // IF INDEXED DB CAPABLE
    if("indexedDB" in window) {
        // OPEN DB
        var openRequest = indexedDB.open("newTabTest",1);
        // CREATE NEW / UPDATE
        openRequest.onupgradeneeded = function(e) {
            // Notify user here: creating database (first time use)
            var thisDB = e.target.result;
            // Create "items" table if it doesn't already exist
            if(!thisDB.objectStoreNames.contains("items")) {
                var store = thisDB.createObjectStore("items", {keyPath: "id", autoIncrement: true});
                store.createIndex("name","name", {unique:true});
                store.createIndex("folder","folder", {unique:false});
                store.createIndex("dial","dial", {unique:false});
            }
        }
        openRequest.onsuccess = function(e) {
            // Success- set db to target result.
            db = e.target.result;
        }
        openRequest.onerror = function(e) {
            // DB ERROR :-(
        }
    }
},false);

// CREATE ITEM FUNCTION
function createItem(n,u,f,c) {
    var transaction = db.transaction(["items"],"readwrite");
    var store = transaction.objectStore("items");
    var item = {
        name: n,
        url: u,
        folder: f,
        colour: c,
        dial: 0,
        order: 100
    }
    var request = store.add(item);
    request.onerror = function(e) {
        console.log("An error occured.");
    }
    request.onsuccess = function(e) {
        console.log("Successfully added.")
    }
};

// GET ITEM(S) FUNCTION
// Specify index and key value OR omit for all
function getItems(callback, ind, key) {
    var transaction = db.transaction(["items"],"readonly");
    var store = transaction.objectStore("items");
    var response = [];

    // If args are omitted - grab all items
    if(!ind | !key) {
        var cursor = store.openCursor();
        cursor.onsuccess = function(e) {
            var res = e.target.result;
            if(res) {
                var r = {
                    "name": res.value['name'],
                    "url": res.value['url'],
                    "folder": res.value['folder'],
                    "colour": res.value['colour'],
                    "dial": res.value['dial'],
                    "order": res.value['order']
                };
                response.push(r);
                res.continue();
            }
        }
        cursor.oncomplete = function() {
            callback(response);
        }
    } else {
        // If both args are specified query specified index
        store = store.index(ind);
        var range = IDBKeyRange.bound(key, key);
        store.openCursor(range).onsuccess = function(e) {
            var res = e.target.result;
            if(res) {
                var r = {
                    "name": res.value['name'],
                    "url": res.value['url'],
                    "folder": res.value['folder'],
                    "colour": res.value['colour'],
                    "dial": res.value['dial'],
                    "order": res.value['order']
                };
                response.push(r);
                res.continue();
            }
        }
        cursor.oncomplete = function() {
            callback(response);
        }
    }
};

最佳答案

正如您在评论中指出的那样,您必须将依赖于数据库的操作保留在从 success 处理程序调用的函数中。

这种基于回调的编程很快就会变得很痛苦,常见的解决方案是使用 promises .

但是,让 IndexedDB 与 Promise 配合使用仍在进行中(如果您感兴趣,请参阅 https://github.com/inexorabletash/indexeddb-promises)。

如果您的目标是完成某件事(而不是学习纯粹的 IndexedDB API),也许您最好找到 wrapper library for IndexedDB (不过不能推荐一个,因为我还没有尝试认真地与 IDB 合作)。

关于javascript - 全局变量只能由第一个函数访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37127713/

相关文章:

javascript - 单击同一标记两次将打开两个信息窗口

angular - Dexie db 随着时间的推移变慢

indexeddb - 索引数据库打开不会触发任何回调

javascript - 使用 Javascript 向 IndexedDB 中预先存在的 ObjectStore 添加索引

javascript - Backbone.js subview 渲染

javascript - 使用 AJAX 返回按钮和刷新

javascript - Service Worker 从另一个 Worker 获取数据后响应“获取”

javascript - 如何在异常捕获中获取数据库引用?

javascript - 两个 Node.JS 脚本读取/写入单个 .JSON 文件,但第一个脚本无法修改该文件

javascript - 是否可以将渲染函数放入 Express 的 for 循环中?