indexedDB + web worker 检索数据

前阵子做项目总结一下 indexedDB +web worker 开发中的问题,

mdn 上有 indexedDB 和 webworker 的文档,但是总觉得demo和实际使用有点出入,

项目中遇到的问题

  1. web worker  文档中提到的subworker chrome 并不支持,所以,不建议用,
  2. web worker 及indexedDB 文档demo有点简单,查询是最重要的资料最少
  3. indexedDB 查询出来的数据顺序和写入的顺序不一致(后面会提到)

需求背景

项目是内部项目只支持最新版本流览器

为什么要用indexedDB ,网上一大堆不再复述

开发中的需求

  1. 初始化数据 把数据写入indexedDB
  2. 更新数据,更新indexedDB
  3. 查询所有数据
  4. 查询指定单个key 所有数据
  5. 查询多个key 所有数据

代码结构划分

  1. 一个worker 负责把数据转换(如果需要的话)
  2. 一个worker 负责把数据写入indexedDB,
  3. 一个worker 负责监听检索消息,然后返回结果
  4. 一个模块负责提供对外操作indexedDB方法,数据检索

代码示例

示例下载 地址

[email protected]:yyccmmkk/testIndexedDB.git

写入indexedDB

示例代码包含完整的代码,这里不细贴出,只说一下写入遇到的问题,【写入顺序和检索结果顺序不致】

什么样的需求要求一致? 比如下拉框里的选择品牌 A开头完了B开头

【解决办法】

objectStore = db.createObjectStore("phones", {keyPath: "index", autoIncrement: true});

创建表时,指定keyPath  并且自增,这样就可以了。

写入前

{
  "mKey":"1",
  "mName":"A 华为",
  "nKey":"11",
  "nName":"HUAWEI Mate系列",
  "oKey":"111",
  "oName":"HUAWEI Mate RS 保时捷",
  "pKey":"1111",
  "pName":"64G",
  "qKey":"11111",
  "qName":"白色"
},

写入后

条件查询

  1. 首先创建索引,
  2. 根据索引进行检索

按条件查询,根据指定的条件查询,比如mKey ,mKey和oKey  ,mKey nKey oKey

首先为了能够被检索 在写入时必须要创建对应的索引,如下图所示,

objectStore.createIndex("mKey", "mKey", {unique: false})

创建名为mKey 的索引,这个索引根据 指定的 mKey 值进行检索,

objectStore.createIndex("mnoKey", ['mKey', 'nKey', 'oKey'], {unique: false});

创建名为 mnoKey 的索引, 它根据指定的mKey nKey oKey 值 进行检索 demo代码已经给出

关于query worker

这个worker 写了三个方法、getMKey、getMapKey、getOKey

getMKey: 使用游标检索指定objectStore内所有数据

getMapKey:使用索引,检索指定 索引值 数据,注意索引值是唯一的

getOKey使用索引 游标 多条件检索数据

class Query {
    //遍历所有品牌
    getMKey(evt) {
        let DBName = evt.data[1];
        let storeName = evt.data[2];
        let flag = evt.data[3];
        let request = indexedDB.open(DBName);
        request.onerror =  (event)=> {
            console.log('indexedDB error!')
        };
        request.onsuccess = (event)=> {
            let db = request.result;
            let transaction = db.transaction([storeName]);
            let objectStore = transaction.objectStore(storeName);
            let openCursor = objectStore.openCursor();
            let temp = [];
            openCursor.onsuccess =  (evt)=> {
                let cursor = evt.target.result;
                if (cursor) {
                    temp.push(cursor.value);
                    cursor.continue();
                }

            };
            transaction.oncomplete = (evt)=> {
                postMessage([temp, flag])
            };

        };
    }

    //提取指定品牌
    getMapKey(evt) {
        let DBName = evt.data[1];
        let storeName = evt.data[2];
        let tempIndex = evt.data[3];
        let id = evt.data[4];
        let request = indexedDB.open(DBName);
        request.onerror = (event) => {
            console.log('indexedDB error!')
        };
        request.onsuccess = (event) => {
            let db = request.result;
            let transaction = db.transaction([storeName]);
            let objectStore = transaction.objectStore(storeName);
            let index = objectStore.index(tempIndex);
            let tempData;
            index.get(id).onsuccess = (event) => {
                tempData = event.target.result;
            };

            transaction.oncomplete = (evt) => {
                postMessage([tempData]);
            };
        };
    }

    getOKey(evt) {
        let DBName = evt.data[1];
        let storeName = evt.data[2];
        let flag = evt.data[3];
        let id = evt.data[4];
        let tempIndex = evt.data[5];
        let isSingle = evt.data[6];
        let request = indexedDB.open(DBName);
        request.onerror = (event) => {
            console.log('indexedDB error!')
        };
        request.onsuccess = (event) => {
            let db = request.result;
            let transaction = db.transaction([storeName]);
            let objectStore = transaction.objectStore(storeName);
            let index = objectStore.index(tempIndex);
            let singleKeyRange = IDBKeyRange.only(id);
            let temp=[];

            let cursor = index.openCursor(singleKeyRange, IDBCursor.NEXT);
            cursor.onsuccess = (evt) => {
                let cursor = evt.target.result;
                if (cursor) {
                    temp.push(cursor.value);
                    !isSingle && cursor.continue();
                }
            };
            cursor.onerror = (evt) => {
                console.log(evt);
            };

            transaction.oncomplete = (evt) => {
                postMessage(temp);
                console.log(temp, flag)
            };

        };
    }
}
let query = new Query();

onmessage = function (evt) {
    query[evt.data[0]](evt)
};

....待续

猜你喜欢

转载自blog.csdn.net/sflf36995800/article/details/80568409