localStorage 根据规范在服务工作者中不可用。原因是因为它提供同步访问,所以必须在启动 JS 环境之前完整读取它,这可能需要一些时间,这与环境本身的启动时间(~50ms)相当,以防存储包含几兆字节(最大为 5MB)。
Service Worker 中只有异步存储 API 可用。
扩展可以使用这些:
-
chrome.storage
- 好:少量简单数据
- 好:直接在内容脚本中可用
- meh:只有与 JSON 兼容的类型(字符串、数字、布尔值、null、由这些类型递归组成的对象/数组),因此尝试存储复杂的东西,如
Set 或 Map 将最终成为一个空对象{} 你必须序列化它们,例如写作时[...mySet],阅读时new Set(result.foo)。
- 不好:大/嵌套数据非常慢
-
IndexedDB
这些 API 是异步的,因此您必须重新编写代码。
由于 Chrome 95 承诺 chrome.storage,我们可以使用 async/await 作为您的示例。
并且不要忘记在 manifest.json 中将 "storage" 添加到 "permissions"。
const LS = chrome.storage.local;
async function pruneStorage() {
const remover = Date.now() - 2500000000;
const key = lastchecked[0];
if ((await LS.get(key))[key] < remover) {
await LS.set({[key]: Date.now()});
} else {
const toRemove = Object.entries(await LS.get())
.map(([k, v]) => v < remover && k)
.filter(Boolean);
if (toRemove.length) {
await LS.remove(toRemove);
}
}
}
或者,模仿localStorage:
const LS = {
getAllItems: () => chrome.storage.local.get(),
getItem: async key => (await chrome.storage.local.get(key))[key],
setItem: (key, val) => chrome.storage.local.set({[key]: val}),
removeItems: keys => chrome.storage.local.remove(keys),
};
async function pruneStorage() {
const remover = Date.now() - 2500000000;
const key = lastchecked[0];
if (await LS.getItem(key) < remover) {
await LS.setItem(key, Date.now());
} else {
const toRemove = Object.entries(await LS.getAllItems())
.map(([k, v]) => v < remover && k)
.filter(Boolean);
if (toRemove.length) {
await LS.removeItems(toRemove);
}
}
}
警告:如果您想异步发送响应,请不要让您的 chrome.runtime.onMessage 侦听器 async,而是使用异步 IIFE 或单独的函数 more info。