当前位置:   article > 正文

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

【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()
    })
  })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

为什么会这样?

经过查找资料发现,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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

步骤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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/718370
推荐阅读
相关标签
  

闽ICP备14008679号