写点什么

神奇,前端不用 redis 也能实现消息队列——indexedDB

作者:DisonTangor
  • 2023-04-06
    上海
  • 本文字数:1628 字

    阅读完需:约 5 分钟

神奇,前端不用redis也能实现消息队列——indexedDB

引言

在 JS 开发过程中,我们常常会用到 async/await 的写法,来实现异步编程,但是这样的操作也会产生并发编程的常见问题。在后端处理上,我们会使用共享内存的 lock 锁机制,CSP/Actor 机制等常见的类库方案,也会使用 sqlite、mysql、redis 这些具备 transaction(事务)特性的数据库来实现消息队列。而此次在 Browser 前端开发中,我尝试用 IndexedDB 来实现对 async/await 的解决方案。

什么是 IndexedDB

在浏览器中,我们更多接触到的是 Cookie 和 LocalStorage。


在 mdn 中是这样介绍:


IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象数据库。IndexedDB 允许您存储和检索用键索引的对象;可以存储结构化克隆算法支持的任何对象。您只需要指定数据库模式,打开与数据库的连接,然后检索和更新一系列事务。
复制代码

如何使用 IndexedDB

IndexedDB 版本支持情况


玩前端的都知道浏览器种类繁多,什么 chrome 系,webkit 系,firefox 系等。这里我建议使用 JS 库——jakearchibald/idb

引用

Using npm


$ npm install idb
// demo.jsimport { openDB, deleteDB, wrap, unwrap } from 'idb';
async function doDatabaseStuff() {const db = await openDB(…);}
复制代码


Using browser


  1. modules 写法

  2. 外部引用

基本操作

检测 IndexedDB API 是否生效


(() => {    'use strict'
if (!('indexedDB' in window)) { console.warn('IndexedDB not supported') return }
//...IndexedDB code})()
复制代码


连接 DB


(async () => {    //...
const dbName = 'mydbname' const storeName = 'store1' const version = 1 //versions start at 1
const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) } })})()
复制代码


创建数据


(async () => {//...const dbName = 'mydbname'const storeName = 'store0'const version = 1	const db = await openDB(dbName, version,{        upgrade(db, oldVersion, newVersion, transaction) {        const store = db.createObjectStore(storeName)        store.put('Hello world!', 'Hello')        }    })})()
复制代码


带事务创建数据


(async () => {    //...    const dbName = 'mydbname'    const storeName = 'store0'    const version = 1
const db = await openDB(/* ... */)
const tx = db.transaction(storeName, 'readwrite') const store = await tx.objectStore(storeName)
const val = 'hey!' const key = 'Hello again' const value = await store.put(val, key) await tx.done})()
复制代码


根据 Key 读取数据


const key = 'Hello again'const item = await db.transaction(storeName).objectStore(storeName).get(key)
复制代码


读取所有 keys 数据


const items = await db.transaction(storeName).objectStore(storeName).getAllKeys()
复制代码


读取所有 values 数据


const items = await db.transaction(storeName).objectStore(storeName).getAll()
复制代码


删除数据库


const dbName = 'mydbname'await deleteDB(dbName)
复制代码


根据 Key 删除数据


(async () => {    //...
const dbName = 'mydbname' const storeName = 'store1' const version = 1
const db = await openDB(dbName, version, { upgrade(db, oldVersion, newVersion, transaction) { const store = db.createObjectStore(storeName) } })
const tx = await db.transaction(storeName, 'readwrite') const store = await tx.objectStore(storeName)
const key = 'Hello again' await store.delete(key) await tx.done})()
复制代码


清除数据


await store.clear();
复制代码


引用 A quick but complete guide to IndexedDB and storing data in browsers

发布于: 刚刚阅读数: 4
用户头像

DisonTangor

关注

怀揣一个武侠梦的男孩 2020-07-29 加入

还未添加个人简介

评论

发布
暂无评论
神奇,前端不用redis也能实现消息队列——indexedDB_前端_DisonTangor_InfoQ写作社区