最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to refactor global variables when using asynchronous chrome.storage? - Stack Overflow

programmeradmin4浏览0评论

To remove the global variables used in a persistent MV2 background script when migrating to an MV2 event page or MV3 service worker, all the guides I've found have just given an example of replacing a single global variable with a few lines of setting and then getting using chrome.storage, but it's still not clear to me how it can be used in a bit more plicated scenario.

For instance:

const activatedTabs = [];
let lastActiveTabInfo;
chrome.tabs.onActivated.addListener((activeInfo) => {
  if (activatedTabs.length === 0) {
    activatedTabs.push(activeInfo.tabId);
    lastActiveTabInfo = activeInfo;
  }
}

How could the snippet above be refactored to use chrome.storage and remove the global variables?

To remove the global variables used in a persistent MV2 background script when migrating to an MV2 event page or MV3 service worker, all the guides I've found have just given an example of replacing a single global variable with a few lines of setting and then getting using chrome.storage, but it's still not clear to me how it can be used in a bit more plicated scenario.

For instance:

const activatedTabs = [];
let lastActiveTabInfo;
chrome.tabs.onActivated.addListener((activeInfo) => {
  if (activatedTabs.length === 0) {
    activatedTabs.push(activeInfo.tabId);
    lastActiveTabInfo = activeInfo;
  }
}

How could the snippet above be refactored to use chrome.storage and remove the global variables?

Share Improve this question edited Oct 31, 2023 at 14:18 woxxom 74k14 gold badges156 silver badges160 bronze badges asked Jul 23, 2022 at 10:35 aderchoxaderchox 4,0932 gold badges36 silver badges47 bronze badges 1
  • A bit off topic but just curious, what's the reason to push to activatedTabs only if it's empty? Doesn't it only keep track of the first activated tab? – pkacprzak Commented Sep 21, 2022 at 11:16
Add a ment  | 

1 Answer 1

Reset to default 12

The number of variables in the state doesn't change the approach:

  1. read the state on the start of the script
  2. save the state on change

You can use global variables as long as you await for their initialization.

For small data (1MB total) use chrome.storage.session, which is in-memory i.e. it doesn't write to disk, otherwise use chrome.storage.local. Both can only store JSON-patible types i.e. string, number, boolean, null, arrays/objects of such types. There's also IndexedDB for Blob or Uint8Array.

Separate variables

let activatedTabs;
let lastActiveTabInfo;
let busy = chrome.storage.session.get().then(data => {
  activatedTabs = data.activatedTabs || [];
  lastActiveTabInfo = data.lastActiveTabInfo;
  busy = null;
});
const saveState = () => chrome.storage.session.set({
  activatedTabs,
  lastActiveTabInfo,
});

chrome.tabs.onActivated.addListener(async info => {
  if (!activatedTabs.length) {
    if (busy) await busy;
    activatedTabs.push(info.tabId);
    lastActiveTabInfo = info;
    await saveState();
  }
});

Single object with properties

const state = {
  activatedTabs: [],
  lastActiveTabInfo: null,
};
const saveState = () => chrome.storage.session.set({ state });
let busy = chrome.storage.session.get('state').then(data => {
  Object.assign(state, data.state);
  busy = null;
});

chrome.tabs.onActivated.addListener(async info => {
  if (!state.activatedTabs.length) {
    if (busy) await busy;
    state.activatedTabs.push(info.tabId);
    state.lastActiveTabInfo = info;
    await saveState();
  }
});

If you change storage outside the background script

...then you'll need to subscribe to chrome.storage.onChanged event.

Notes

Note that if you subscribe to frequent events like tabs.onActivated, your service worker may restart hundreds of times a day, which wastes much more resources than keeping an idle persistent background page. The Chromium team ignores this problem, but you shouldn't, and luckily there's a way to reduce the number of restarts by prolonging the SW lifetime. You still need to read/save the state as shown.

发布评论

评论列表(0)

  1. 暂无评论