javascript 一个简单的indexedDB包装器功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript 一个简单的indexedDB包装器功能相关的知识,希望对你有一定的参考价值。

    // 待写入数据
    const users = [
      {
        userID: '001',
        username: 'Cherry'
      },
      {
        userID: '002',
        username: 'Rachel'
      },
      {
        userID: '003',
        username: 'Amy'
      },
      {
        userID: '004',
        username: 'david'
      },
      {
        userID: '005',
        username: 'Mia'
      }
    ];


    /**
     * useIndexedDB() useIndexedDB() 利用indexedDB进行单条数据的增删改查,还支持获取或删除数据库的所有数据
     *
     * @param {String} action 数据库操作行为,getAll|get|add|update|remove|removeAll
     * @param {String|Object} dataParam 与行为对应的数据参数
     *        getAll|removeAll 不需要参数,
     *        add|update 需要一个想要新增或更新的数据object,
     *        get|remove 需要一个数据库主值的value
     * @param {String} dbName 数据库名称,默认为testing
     * @param {Number} version 数据库版本号,为正整数,默认为1
     * @param {String} objectStorageName 对象存储空间名称,相对于SQL的table name,默认为users
     * @param {String} keyPath 对象存储空间的主值(对象中的属性名称),相对于table中检索使用的key,在当前对象存储空间中,对象的该属性值必须唯一,不能重复
     * @param {String} accessMode 事务的访问模式,readonly|readwrite|versionchange,默认为readwrite
     * @returns {Array} 返回查询行为结果的数组
     */
    function useIndexedDB(action, dataParam, dbName='testing', version=1, objectStorageName='users', keyPath='userID', accessMode='readwrite') {
      const result = [];
      // 创建数据库连接
      const request = indexedDB.open(dbName, version);

      request.onerror = function (event) {
        console.log('Something bad happened while trying to open: ' + event.target.errorCode);
      };

      request.onupgradeneeded = function () {
        const db = request.result;
        // 创建存储空间
        const store = db.createObjectStore(objectStorageName, { keyPath: keyPath });
        // const index = store.createIndex('NameIndex', 'username');
      };

      request.onsuccess = function () {
        const db = request.result;

        // 事务 - 读取与修改操作
        const transaction = db.transaction('users', accessMode);
        const objectStore = transaction.objectStore('users');

        transaction.onabort = function (event) {
          console.log('tx has been aborted.');
          console.log(event.target);
        };

//         let i = 0;

//         // 数据写入
//         while(i < users.length) {
//           const req = objectStore.put(users[i++]);
//           req.onerror = function (event) {
//             console.log(event.target);
//           }
//         }

        let newRequest;

        // getAll() 并不是indexedDB中的标准方法,但在当前的chrome中是可以使用的,是否增加游标查询支持
        if (typeof objectStore.getAll === 'function' && action === 'getAll') {
          newRequest = objectStore.getAll();
        }

        if (action === 'get') {
          newRequest = objectStore.get(dataParam);
        }
        // add(),发现数据库中有一样的键值对象时,会返回一个错误,事务将会终止,可以防止数据被重新添加
        // 但没关系,下一次调用dealDataWithIndexedDB()会重新建立一次数据库连接,新建一个新的事务
        // 其实,使用put()也没问题,数据有更新就覆盖,没有就相对于重写一遍
        // if (action === 'add') {
        //   newRequest = objectStore.add(dataParam);
        // }

        if (action === 'add' || action === 'update') {
          newRequest = objectStore.put(dataParam);
        }

        if (action === 'remove') {
          newRequest = objectStore.delete(dataParam);
        }

        if (action === 'removeAll') {
          newRequest = objectStore.clear();
        }

        newRequest.onerror = function (event) {
          console.log(event.target);
        };
        newRequest.onsuccess = function (event) {
          console.log(event.target.result);
          if (action === 'getAll') {
            result.push(...newRequest.result);
          }
          if (action === 'get') {
            result.push(newRequest.result);
          }
        };

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

      // let dataParam = dealDataWithIndexedDB('getAll');
      // !似乎没问题,由于js中对象赋值为浅拷贝,等事件完成后,会往result里push数据对象,相应的更新也会给到dataParam变量。
      // 潜在的风险是,数据很多,没来得及把所有数据对象push到result中,而dataParam已经被用于DOM渲染中。
      return result;
    }

以上是关于javascript 一个简单的indexedDB包装器功能的主要内容,如果未能解决你的问题,请参考以下文章

javascript 非常简单的IndexedDB示例

javascript 非常简单的IndexedDB示例

如何从 JavaScript 中删除整个 IndexedDB 数据库?

Javascript:使用多个索引搜索 indexeddb

javascript indexedDB错误情况

无法使用可读格式的 JavaScript 读取 IndexedDB sqlite 文件