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

最近俺在接触 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;
}
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值