【Chrome插件】如何在Chrome插件开发中处理复杂数据结构的存储?

简介: 在Chrome插件开发中,遇到问题:存储包含Map和数组的复杂数据结构到`chrome.storage.local`时,读取为空。原因在于`chrome.storage.local`只支持JSON序列化,而Map无法直接序列化。解决方案是使用`serializeMap`和`deserializeMap`方法将Map转换为数组进行存储和读取。更新的`saveMindData`和`getMindData`方法实现了数据的正确序列化和反序列化。

问题描述

最近俺在接触 Chrome 插件开发,需要把一个数据存放到浏览器的存储中。这个数据结构有点复杂,它包含一个 Map 和一个数组。我使用 chrome.storage.local API来存储这个数据,然后在另一个地方获取数据。保存数据的代码并没有报错,但是俺发现获取的时候获取结果的内容为空,这是为什么呢?

下面是我封装的保存数据和获取数据的方法:

// 要存储的数据结构
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可以很好地处理对象和数组,但对于MapSet等ES6中引入的复杂数据结构,JSON是无法直接序列化和反序列化的。因此,尽管你可能没有在保存数据时遇到错误,但在尝试读取非JSON兼容类型的数据时,这些数据将因无法被正确序列化而丢失。

解决方案

总之一句话:chrome.storage.local 只能存储 JSON 兼容的数据类型(如对象、数组、字符串、数字等),MapSet 需要转换为对象或数组才能正确存储。在这里,我们通过 chrome.storage.local 存储时需要先进行序列化处理,而在读取时需要进行反序列化处理。

步骤1: 序列化和反序列化Map对象

我们先增加两个方法做序列化的处理,serializeMapdeserializeMap 方法用于将 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: 存储和读取数据

然后再增加操作数据的方法,saveMindDatagetMindData 方法用于保存和获取 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;
}
目录
相关文章
|
14天前
|
存储 C语言
数据结构中的线性表链式存储介绍及其基本操作
链式存储是线性表的一种重要存储方式,它通过节点和指针的结构,实现了灵活的动态存储管理。本文介绍了单向链表的基本操作,并提供了相应的C语言代码示例。理解和掌握链表的操作对学习和应用数据结构具有重要意义。希望这篇博客能帮助你更好地理解线性表的链式存储。
25 2
|
1月前
|
存储 监控 NoSQL
Redis处理大量数据主要依赖于其内存存储结构、高效的数据结构和算法,以及一系列的优化策略
【5月更文挑战第15天】Redis处理大量数据依赖内存存储、高效数据结构和优化策略。选择合适的数据结构、利用批量操作减少网络开销、控制批量大小、使用Redis Cluster进行分布式存储、优化内存使用及监控调优是关键。通过这些方法,Redis能有效处理大量数据并保持高性能。
53 1
|
1天前
|
存储 JavaScript 前端开发
JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)
【6月更文挑战第25天】JavaScript中的对象是数据结构,存储键值对,键为字符串,值可为任意类型,包括函数(作为方法)。
8 2
|
1天前
|
Web App开发
推荐一款chrome阅读插件
推荐一款chrome阅读插件
12 2
|
4天前
|
存储 JavaScript 前端开发
JavaScript中的数组是核心数据结构,用于存储和操作序列数据
【6月更文挑战第22天】JavaScript中的数组是核心数据结构,用于存储和操作序列数据。创建数组可以使用字面量`[]`或`new Array()`。访问元素通过索引,如`myArray[0]`,修改同样如此。常见方法包括:`push()`添加元素至末尾,`pop()`移除末尾元素,`shift()`移除首元素,`unshift()`添加到开头,`join()`连接为字符串,`slice()`提取子数组,`splice()`进行删除、替换,`indexOf()`查找元素位置,`sort()`排序数组。还有其他如`reverse()`、`concat()`等方法。
14 2
|
20天前
|
存储 算法
数据结构和算法学习记录——二叉树的存储结构&二叉树的递归遍历(顺序存储结构、链表存储结构、先序中序后序递归遍历)
数据结构和算法学习记录——二叉树的存储结构&二叉树的递归遍历(顺序存储结构、链表存储结构、先序中序后序递归遍历)
11 0
数据结构和算法学习记录——二叉树的存储结构&二叉树的递归遍历(顺序存储结构、链表存储结构、先序中序后序递归遍历)
|
1月前
|
存储 机器学习/深度学习 人工智能
数据结构(五)----特殊矩阵的压缩存储
数据结构(五)----特殊矩阵的压缩存储
32 3
|
19天前
|
Web App开发 前端开发 安全
Chrome 插件打包发布
Chrome 插件打包发布
22 0
|
19天前
|
Web App开发 JSON JavaScript
Chrome 插件各模块之间的消息传递
Chrome 插件各模块之间的消息传递 一、消息传递 1. 消息传递分类 Chrome 插件的 Action、Background 和 content_script 三个模块之间的信息传输 插件和插件之间的信息传输 网页向插件进行信息传输 与原生应用进行消息传递
16 0
|
19天前
|
Web App开发 JavaScript
使用CRXjs、Vite、Vue 开发 Chrome 多页面插件,手动配置 vite.config.ts 和 manifest.json 文件
使用CRXjs、Vite、Vue 开发 Chrome 多页面插件,手动配置 vite.config.ts 和 manifest.json 文件
25 0