【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储
最近俺在接触 Chrome 插件开发,需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂,它包含一个 Map 和一个数组。我使用
chrome.storage.localAPI来存储这个数据,然后在另一个地方获取数据。保存数据的代码并没有报错,但是俺发现获取的时候获取结果的内容为空,这是为什么呢?
下面是我封装的保存数据和获取数据的方法:
// 要存储的数据结构
const mindDataObj = {keywordMap: new Map(),mindDataArr: []
};/*** 获取存储对象* @param {string} key 存储对象的键* @returns {Promise<Object>} 返回一个包含存储对象的 Promise*/
export async function getObject(key) {return new Promise((resolve, reject) => {chrome.storage.local.get([key], (result) => {if (chrome.runtime.lastError) {return reject(chrome.runtime.lastError)}resolve(result[key] || {})})})
}/*** 保存存储对象* @param {string} key 存储对象的键* @param {Object} obj 要保存的对象* @returns {Promise<void>} 返回一个 Promise,表示操作完成*/
export async function saveObject(key, obj) {return new Promise((resolve, reject) => {chrome.storage.local.set({ [key]: obj }, () => {if (chrome.runtime.lastError) {return reject(chrome.runtime.lastError)}resolve()})})
}
为什么会这样?
经过查找资料发现,chrome.storage.local 的存储机制只能存储和检索序列化的 JSON 对象,虽然JSON可以很好地处理对象和数组,但对于Map、Set等ES6中引入的复杂数据结构,JSON是无法直接序列化和反序列化的。因此,尽管你可能没有在保存数据时遇到错误,但在尝试读取非JSON兼容类型的数据时,这些数据将因无法被正确序列化而丢失。
解决方案
总之一句话:chrome.storage.local 只能存储 JSON 兼容的数据类型(如对象、数组、字符串、数字等),Map 和 Set 需要转换为对象或数组才能正确存储。在这里,我们通过 chrome.storage.local 存储时需要先进行序列化处理,而在读取时需要进行反序列化处理。
步骤1: 序列化和反序列化Map对象
我们先增加两个方法做序列化的处理,serializeMap 和 deserializeMap 方法用于将 Map 对象转换为数组,从而可以存储在 chrome.storage.local 中,并在读取时将其转换回 Map 对象。
/*** 序列化Map对象* @param {Map} map 要序列化的Map对象* @returns {Object} 序列化后的对象*/
function serializeMap(map) {return Array.from(map.entries());
}/*** 反序列化Map对象* @param {Array} entries 序列化后的对象* @returns {Map} 反序列化后的Map对象*/
function deserializeMap(entries) {return new Map(entries);
}
步骤2: 存储和读取数据
然后再增加操作数据的方法,saveMindData 和 getMindData 方法用于保存和获取 mindDataObj 格式的数据,包括序列化和反序列化步骤。
/*** 保存mindDataObj格式的数据* @param {string} key 存储对象的键* @param {Object} initMindDataObj 要保存的对象* @returns {Promise<void>} 返回一个 Promise,表示操作完成*/
export async function saveMindData(key, mindDataObj) {const serializedData = {keywordMap: serializeMap(mindDataObj.keywordMap),mindDataArr: mindDataObj.mindDataArr};await saveObject(key, serializedData);
}/*** 获取mindDataObj格式的数据* @param {string} key 存储对象的键* @returns {Promise<Object>} 返回一个包含mindDataObj格式数据的 Promise*/
export async function getMindData(key) {const serializedData = await getObject(key);const mindDataObj = {keywordMap: deserializeMap(serializedData.keywordMap || []),mindDataArr: serializedData.mindDataArr || []};return mindDataObj;
}
相关文章:
【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储
最近俺在接触 Chrome 插件开发,需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂,它包含一个 Map 和一个数组。我使用 chrome.storage.local API来存储这个数据,然后在另一个地方获取数据。保存数据的代码并没有报错,但…...
MySQL 保姆级教程(二):使用 MySQL 检索数据
使用 MySQL 3.2 选择数据库 使用数据库: 输入: USE 数据库名;输出: Database changed分析: 不返回任何结果,显示某种形式的通知 例如: 使用 crashcourse 数据库 use crashcourse; 3.3 了解数据库和表 列出所有的数据库: 输入: SHOW DATABASES;输出: --------…...
Sui Bridge在测试网上线并推出10万SUI激励计划
是一种为Sui设计的原生桥接协议,专门用于在Sui与其他网络之间桥接资产和数据。今天,Sui Bridge宣布在测试网上线。作为一种原生协议,Sui Bridge能够在Ethereum和Sui之间轻松且安全地转移ETH、wBTC、USDC和USDT,使其成为Sui基础设施…...
Spring系统学习 - Bean的作用域
bean作用域介绍 Spring框架提供了不同的作用域来管理Bean的生命周期和可见性,这对于控制不同类型的组件和处理并发请求尤其重要。 singleton(默认): 每个Spring IoC容器只有一个bean实例。当容器创建bean后,它会被缓存…...
贪吃蛇双人模式设计(2)
敲上瘾-CSDN博客控制台程序设置_c语言控制程序窗口大小-CSDN博客贪吃蛇小游戏_贪吃蛇小游戏csdn-CSDN博客 一、功能实现: 玩家1使用↓ → ← ↑按键来操作蛇的方向,使用右Shift键加速,右Ctrl键减速玩家2使用W A S D按键来操作蛇的方向&am…...
mysql什么时候不需要建立索引
WHERE 条件,GROUP BY,ORDER BY 里用不到的字段,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的,因为索引是会占用物理空间的。字段中存在大量重复数据,不需要创建索引,比如性…...
热门开源项目推荐:技术与地址概览
随着开源项目的不断兴起,越来越多的优秀项目涌现出来,为开发者们提供了丰富的资源和灵感。在此,我将为大家推荐几个热门的开源项目,并附上它们的开源地址,以供大家参考和了解。 1. TensorFlow 项目简介: …...
Golang的channel
目录 基本使用 channel 数据结构 阻塞的协程队列 协程节点 构建 channel 写流程 读流程 非阻塞与阻塞 closechan(关闭) 基本使用 创建无缓存 channel c : make(chan int) //创建无缓冲的通道 cc : make(chan int,0) //创建无缓冲的通道 c 创建有缓存 channel c : m…...
DIYGW可视化开发工具:微信小程序与多端应用开发的利器
一、引言 随着移动互联网的飞速发展,微信小程序以其轻便、易用和跨平台的特点受到了广泛关注。然而,微信小程序的开发相较于传统的H5网页开发,在UI搭建和交互设计上存在一定的挑战。为了应对这些挑战,开发者们一直在寻找更加高效…...
docker——基础知识
简介 一、什么是虚拟化和容器化 实体计算机叫做物理机,有时也称为寄主机; 虚拟化:将一台计算机虚拟化为多台逻辑计算机; 容器化:一种虚拟化技术,操作系统的虚拟化;将用户空间软件实…...
SAP MMRV/MMPV 物料账期月结月底月初开关
公告:周一至周五每日一更,周六日存稿,请您点“关注”和“在看”,后续推送的时候不至于看不到每日更新内容,感谢。 这是一条刮刮乐,按住全部选中:点关注的人最帅最美,欢迎࿱…...
五分钟看懂如何解决FP独立站的广告投放问题
在数字化时代的浪潮中,跨境电商的独立站成为了商家们的新宠。与传统的电商平台相比,独立站在品牌建设、市场定位以及客户体验上提供了更多的自由度和创新空间。然而,这些独立站尤其是销售FP产品的站点,在广告投放上遇到了重重障碍…...
学习分享-FutureTask
前言 今天再改简历的时候回顾了之前实习用到的FutureTask,借此来回顾一下相关知识。 FutureTask 介绍 FutureTask 是 Java 并发包(java.util.concurrent)中的一个类,用于封装异步任务。它实现了 RunnableFuture 接口࿰…...
Javaweb02-XML概述
第一章 XML概述 1.XML基本概念 什么是xml? **a.**引入的原因:为了解决不同不同语言之间的数据传输的格式不同 **b.**概念:XML是一种可扩展标记语言,适用于不同数据之间的数据交换 **c.**XML文档:通过元素的嵌套&a…...
Linux shell编程基础
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问 Linux 内核的服务。 Shell 脚本&#x…...
2024.6.12 作业 xyt
今日课堂练习:vector构造函数 #include <iostream> #include <vector> using namespace std;void printVector(vector<int> &v) {vector<int>::iterator iter;for(iterv.begin(); iter ! v.end(); iter){cout << *iter <<…...
QTTabBar在重置Internet Explorer后失效
网上常见的办法是: 打开IE浏览器>>设置>>Internet选项>>高级。勾选启用第三方浏览器扩展,重启后生效。 打开IE浏览器-设置–管理加载项,启用QTTabBar。 实际在Win10上使用的时候会遇到点开IE自动跳转到Edge的问题。这时…...
Django之云存储(一)
一、介绍 用户上传的文件以及项目中使用的静态文件,除了保存在本地服务器,还在可以保存在云服务中,比如: 阿里云七牛云(课程选用)亚马逊云等1.1、使用方式 注册账号 七牛云开发者平台 实名认证 创建空间...
推挽与开漏输出
一般来说,微控制器的引脚都会有一个驱动电路,可以配置不同类型的数字和模拟电路接口。输出模式一般会有推挽与开漏输出。 推挽输出 推挽输出(Push-Pull Output),故名思意能输出两种电平,一种是推…...
Sora和快手可灵背后的核心技术 | 3DVAE:通过小批量特征交换实现身体和面部的三维形状变分自动编码器
【摘要】学习3D脸部和身体生成模型中一个解开的、可解释的和结构化的潜在表示仍然是一个开放的问题。当需要控制身份特征时,这个问题尤其突出。在本文中,论文提出了一种直观而有效的自监督方法来训练一个3D形状变分自动编码器(VAE),以鼓励身份特征的解开潜在表示。通过交换不同…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
