我觉得IndexedDB挺有意思的,可以学习一下~

前言

关于IndexedDB,之前有一些博主已经出过一些文章了,写的都很好,也推荐大家去看看

我们知道,现在大部分的前端面试都喜欢搞一些并不太常见的问题,于是前端内存在今年问的开始多了起来,那么既然说到前端内存了,不免会去说webstorage,但是webstorage已经被问烂了,那么面试就会选择问不那么普遍的IndexedDB

这里我们不去关注别的,例如Web Storage,我们就来说IndexedDB

我想带着我最开始学习它的思维,带着大家直观感受一下IndexedDB:什么是IndexedDB,IndexedDB和websql的区别,IndexedDB需要写sql吗等,通过抽象的问题来进行循序渐进地了解

好,那我们开始吧

什么是IndexedDB

注:这里的RDBMS是指关系型数据库

MDN给的定义是这样的,比较抽象,但是我们可以简单理解

IndexedDB是客户端存储的一种方式,这种方式是一种数据库的方式,并且是非关系型数据库,既然是数据库了,那么它更适合存储大量的数据,并且有高效的查询方式

而对比之下webstorage是简单键值对的存储方式,简单,而且存储量较少

说到数据库这里,我觉得可以说一下websql,因为这个老的方案听起来更像和数据库有关

websql和IndexedDB的区别

这里咱们稍微了解一下websqlwebsql是在IndexedDB之前就有的,就像他的名字一样,它也是一种数据库形式的内存方式

但是它是需要写sql的,它引入了一组使用 SQL 操作客户端数据库的 API

  • 三个核心方法

    1. openDatabase:使用数据库或新建数据库来创建数据库对象
    2. transaction:允许我们根据情况控制事务提交或回滚
    3. executeSql:这个方法用于执行真实的 SQL 查询
js 复制代码
// 打开或创建数据库
var db = openDatabase('mydb', '1.0', 'My Database', 2 * 1024 * 1024);

// 创建表
db.transaction(function (tx) {
  tx.executeSql('CREATE TABLE IF NOT EXISTS users (id unique, name, email)');
});

// 插入数据
db.transaction(function (tx) {
  tx.executeSql('INSERT INTO users (id, name, email) VALUES (?, ?, ?)', [1, 'shaka', 'shaka@virgo.com']);
});

// 查询数据
db.transaction(function (tx) {
  tx.executeSql('SELECT * FROM users', [], function (tx, result) {
    var rows = result.rows;
    for (var i = 0; i < rows.length; i++) {
      console.log('ID: ' + rows[i].id + ', Name: ' + rows[i].name + ', Email: ' + rows[i].email);
    }
  });
});

// 更新数据
db.transaction(function (tx) {
  tx.executeSql('UPDATE users SET name = ? WHERE id = ?', ['laka', 1]);
});

// 删除数据
db.transaction(function (tx) {
  tx.executeSql('DELETE FROM users WHERE id = ?', [1]);
});

就像这样

需要知道是websql就是异步的,不会阻塞JavaScript线程,从而保持页面的响应性,所以作为websql的进阶版IndexedDB也是异步的

其实我觉得这就像非关系型数据库MongoDB 一样,非关系型数据库慢慢崛起,而且似乎和前端更为密切,所以IndexedDB也会如此发展

IndexedDB特点

说了这么多,咱们总的说一下IndexedDB的特点,并对特殊的带上解释

  1. 存储量大
  2. 键值对存储模型:IndexedDB采用键值对的存储模型,其中每个存储对象都有一个唯一的键和对应的值。
  3. 支持事务操作
  4. 支持索引:IndexedDB支持创建索引,以便在数据存储中更快地进行查询和排序。通过创建索引,可以提高数据检索的性能。
  5. 支持异步。
  6. 同源:IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库

关于IndexedDB怎么用的,其实比较繁琐

但是我们大致可以分这几步

  1. 打开数据库
  2. 创建对象存储空间
  3. 启动事务
  4. 执行数据操作
js 复制代码
// 打开或创建数据库
const request = indexedDB.open('myDatabase', 1);

// 定义数据库版本升级时的操作
request.onupgradeneeded = function(event) {
  const db = event.target.result;

  // 创建对象存储空间
  const objectStore = db.createObjectStore('users', { keyPath: 'id' });

  // 创建索引
  objectStore.createIndex('name', 'name', { unique: false });
};

// 数据库打开成功后的回调函数
request.onsuccess = function(event) {
  const db = event.target.result;

  // 启动事务,并指定操作的对象存储空间
  const transaction = db.transaction(['users'], 'readwrite');
  const objectStore = transaction.objectStore('users');

  // 添加数据
  const user = { id: 1, name: 'shaka', email: 'shaka@virgo.com' };
  const addUserRequest = objectStore.add(user);

  addUserRequest.onsuccess = function() {
    console.log('添加成功');
  };

  addUserRequest.onerror = function() {
    console.error('添加失败');
  };

  // 查询数据
  const getUserRequest = objectStore.get(1);

  getUserRequest.onsuccess = function() {
    const user = getUserRequest.result;
    console.log('User:', user);
  };

  getUserRequest.onerror = function() {
    console.error('获取失败');
  };

  // 提交事务
  transaction.oncomplete = function() {
    db.close();
  };
};

request.onerror = function() {
  console.error('数据库打开失败');
};

我们不重点讨论这种方式,如果想了解具体api或者有需要的话可以去MDN看一下

现在一般用的解决方案是官方都推荐的一个库localForage

localForage

localForage是现在比较常用的一种indexedDB的解决方案,并且pinia就可以管理localForage

关于localForage的使用方式,我就不在这里放代码了,因为在掘金已经有一定的文章了,这是我觉得较清晰,也很不错的文章,当然,还有别的优秀的文章,就不一一列举了

有使用的方式,降级处理,踩坑等,我觉得都蛮有用也蛮有意思的~

juejin.cn/post/727594...

juejin.cn/post/719982...

结尾

我觉得IndexedDB是一个很有意思的点,可以更好地让你了解前端存储,甚至是浏览器

对于localForage,没有过多的介绍,但是如果大家感兴趣的话,可以带着大家走一下源码,或者自己手写一个简单版用来熟悉知识点

其实前端存储是我面试的时候被问到的点,经过今年的很多次面试,我越发觉得今年的面试题并不是常规的八股,会有一些较少数人关注到的知识点

我觉得IndexedDB在这些知识点当中是有意思并且实用的,所以分享给大家

其实IndexedDB还有一些别的有意思的东西,比如存储到用户的哪个文件夹,在你找文件的过程中你还会看到别的有意思的东西,例如历史记录存储啦等等。。所以我觉得带着兴趣去学习,会发现更多的点,并且学的更好,大家加油吧~

相关推荐
web1350858863526 分钟前
前端node.js
前端·node.js·vim
m0_5127446427 分钟前
极客大挑战2024-web-wp(详细)
android·前端
若川36 分钟前
Taro 源码揭秘:10. Taro 到底是怎样转换成小程序文件的?
前端·javascript·react.js
潜意识起点1 小时前
精通 CSS 阴影效果:从基础到高级应用
前端·css
奋斗吧程序媛1 小时前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿1 小时前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
醒了就刷牙1 小时前
黑马Java面试教程_P9_MySQL
java·mysql·面试
m0_748256563 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@3 小时前
HTML5适配手机
前端·html·html5