比较IndexedDB中两个不同存储中的值

时间:2019-06-01 12:13:51

标签: javascript indexeddb

我有两个数据结构:

  1. 任务:taskID(自动递增),标题,状态,到期日期,描述
  2. 标签:tagID,tagName,tagColor,textColor,taskID

我正在尝试比较它们两者的taskID值,以便以后能够将单个任务与多个标签相关联。我已经编写了两个函数,getTags()和getTasks()。我设法遍历了这两个对象,并获得了两个存储区中的所有对象,但是,我不确定如何检查两个值是否匹配。

function connectToDB() {
    window.webkitIndexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

    //check for support
    if(!window.indexedDB) {
        alert("Your browser do not support indexedDB. Please update you browser.")
    }

    //open database "KanbanDatabase" version 9. 
    //db = database, tx = transaction, store = store data, index = index (seach data).
    let request = window.indexedDB.open("KanbanDatabase", 9), 
        db,
        tx,
        store,
        index;

    //when creating a new databse, a store(structure) must be added
    request.onupgradeneeded = function(e) {
        let db = request.result,
        //tasks
        tasksStore = db.createObjectStore("tasksStore",{
            keyPath: "taskID", autoIncrement: true
        }),
        tasksIndex = tasksStore.createIndex("status", "status", {
            unique: false
        }),
        //tags
        tagsStore = db.createObjectStore("tagsStore", {
            keyPath: "tagID", autoIncrement: true
        }),
        tagsIndex = tagsStore.createIndex("tagID", "tagID", {
            unique: true
        });
    };

    //open database will return response. 
    //error handler:
    request.onerror = function(e) {
        console.error("There was an error opening the database: " + e.target.errorCode);
    };

    //success handler:
    request.onsuccess = function(e) {
        console.log("Successfully connected to DB")
        db = request.result;
        //tasks
        tasksTx = db.transaction("tasksStore", "readwrite");
        tasksStore = tasksTx.objectStore("tasksStore");
        tasksIndex = tasksStore.index("status");

        //tags
        tagsTx = db.transaction("tagsStore", "readwrite");
        tagsStore = tagsTx.objectStore("tagsStore");
        tagsIndex = tagsStore.index("tagID");

        db.onerror = function(e) {
            console.error("ERROR " + e.target.errorCode);
        }


        function tagsToTasks() {
            let amountOfTasks = tasksIndex.count();
            let amountOfTags = tagsIndex.count();

            function getTasks() {
                for (var i = 1; i < amountOfTasks.result+1; i++) {
                    let getTasks = tasksStore.get(i);

                    getTasks.onerror = function() {
                        console.error("There was an error looping through the tasks");
                    }

                    getTasks.onsuccess = function() {
                        console.log(getTasks.result.taskID)
                    }
                }
            }

            function getTags() {
                for (var j = 1; j < amountOfTags.result+1; j++) {
                    let getTags = tagsStore.get(j);

                    getTags.onerror = function() {
                        console.error("There was en error looping through the tags");
                    }

                    getTags.onsuccess = function() {
                        let result = getTags.result.taskID;

                        return result;
                    }
                }
            }

            function compareID() {
                //what to do?
            }

            amountOfTasks.onerror = function() {
                console.error("There was an error finding the amount of tasks");
            }

            amountOfTasks.onsuccess = function() {
                getTasks();
            }

            amountOfTags.onerror = function() {
                console.error("There was an error finding the amount of tags");
            }

            amountOfTags.onsuccess = function() {
                getTags();
            }

        }


        //fire functions
        tagsToTasks();
        listTasks();

        //close DB conection once transaction is complete.
        tasksTx.oncomplete = function() {
            db.close();
        }

        tagsTx.oncomplete = function() {
            db.close();
        }
    }
}

编辑:进行澄清:我需要比较两个不同商店中的两个值。问题开始于tagsToTasks()函数。如何比较getTags()函数中的getTags.result.taskID和getTasks()函数中的getTasks.result.taskID返回的值?

1 个答案:

答案 0 :(得分:0)

第一个错误在这里。

window.webkitIndexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;` 

您将其分配给window.webkitIndexedDb,但在下一行中检查window.indexedDb

我建议您使用局部const而不是尝试覆盖全局变量。

像这样

const indexedDb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

if (!indexedDb) return ....

接下来,您可以使用cursorgetAll方法来检索所有对象。另外,您无法从onSuccess事件处理程序返回任务,需要从父范围为它分配一个变量。像这样

let tasks = [];
tasksStore.getAll().onsuccess = function(event) {
   tasks = event.target.result
   attachTags(tasks);
};

function attachTags(tasks) {
  tags.openCursor().onsuccess = function(event) {
  var cursor = event.target.result;
  if (cursor) {
    const task = tasks.find(t => t.taskId == cursor.value.taskId);
    if (!task.tags) task.tags = []
       task.tags.push(cursor.value) ;
    cursor.continue();
  }
  else {
    return;
  }
};
}

看来您必须经历回调地狱才能做到这一点。我正在使用find方法来选择带有cursor指向cursor.value的当前标签的taskId的任务,然后为该任务创建标签数组,并将标签推入其中。查看您的数据模型,我假设您想通过taskId外键将每个标签与相关任务相关联。

设置方式的问题是indexedDB使用回调函数返回值,而在代码中没有地方保存这些值并传递给需要它们的函数。您编写的回调实际上对接收到的值不执行任何操作。您不能从回调中返回值,因为该回调是由API(而不是您的代码)调用的。您需要为回调外部的变量赋值或在回调内部进行处理。回调彼此异步执行,因此无法保证您的代码将按照您编写的顺序执行,这使您别无选择,只能从当前回调中设置下一个回调,这称为回调地狱。承诺有助于缓解这种情况,因此,如果您要在生产中使用它,我建议您使用像这样的库 https://github.com/jakearchibald/idb展示了更多可用的Api。