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方法,数据检索

代码示例

示例下载 地址

git@github.com: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)
};

 

 

 

 

 

....待续

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值