简体   繁体   English

同步同步和本地chrome.storage

[英]Synchronizing sync and local chrome.storage

I would like to know how to handle both local and sync storage in the right way in Chrome extension please. 我想知道如何在Chrome扩展程序中以正确的方式处理本地存储和同步存储。

This is my case: 这是我的情况:
I'm working on an extension for only a specific site (for now), 我目前仅在针对特定网站的扩展程序上工作,
which contains a content-script and a popup. 其中包含一个内容脚本和一个弹出窗口。
The popup contains options where the user can make changes, then the values are sent to the content-script to show the changes on the page. 弹出窗口包含用户可以进行更改的选项,然后将这些值发送到内容脚本以在页面上显示更改。

I'm looking to make as less saving and retrieving storage tasks as possible, and that in the end it will get saved in the sync storage and not just in local. 我希望尽可能减少保存和检索存储任务,最后将其保存在同步存储中,而不仅仅是保存在本地。
The sync storage got a per-minute limit, where the local one doesn't. 同步存储有每分钟的限制,而本地没有。

I know how to listen to the popup closed call from the content-script using a long-lived connection and listen to the onConnect and onDisconnect , and then I can do a save task, but is there a better way to save reading and writing to the storage? 我知道如何使用长期连接从内容脚本监听弹出式关闭调用,并监听onConnectonDisconnect ,然后可以执行保存任务,但是有更好的方法来保存对存储空间?
All I can think of was having a background script where I can store the changes in variables and then just send them back and forward to and from the content-script and popup, so it's like having a storage without actually using the storage, but then how can I detect when the user leaves the specific domain and then do the single saving task, and also close/stop the background/event script? 我所能想到的就是拥有一个后台脚本,我可以在其中存储变量中的更改,然后将它们发送来回传递至内容脚本和弹出窗口,这样就好比拥有一个存储而不实际使用该存储,但是如何检测用户何时离开特定域,然后执行单个保存任务,以及关闭/停止后台/事件脚本?

The current limit on chrome.storage.sync sustained operations is 1 every 2 seconds (more accurately 1800 per hour), and a burst rate limit of 120 per minute. chrome.storage.sync持续操作的当前限制是每2秒1(更准确地说是每小时1800),并且突发速率限制为每分钟120。

So, your job is to ensure sync happens no more often than once per 2 seconds. 因此,您的工作是确保同步发生的频率不超过每2秒一次。

I would make an event page that deals with chrome.storage.onChanged event and syncs the two areas. 我将创建一个处理chrome.storage.onChanged事件并同步两个区域的事件页面。 Which is a surprisingly hard task due to local echo! 由于局部回声,这是一项令人惊讶的艰巨任务!

// event.js, goes into background.scripts in manifest

// Those will not persist if event page is unloaded
var timeout;
var queuedChanges = {};
var syncStamp = 1;

chrome.storage.onChanged.addListener(function(changes, area) {
  // Check if it's an echo of our changes
  if(changes._syncStamp && changes._syncStamp.newValue == syncStamp) {
    return;
  }

  if(area == "local") {
    // Change in local storage: queue a flush to sync

    // Reset timeout
    if(timeout) { clearTimeout(timeout); }

    // Merge changes with already queued ones
    for(var key in changes) {
      // Just overwrite old change; we don't care about last newValue
      queuedChanges[key] = changes[key];
    }

    // Schedule flush
    timeout = setTimeout(flushToSync, 3000);

  } else {
    // Change in sync storage: copy to local

    if(changes._syncStamp && changes._syncStamp.newValue) {
      // Ignore those changes when they echo as local
      syncStamp = changes._syncStamp.newValue;
    }
    commitChanges(changes, chrome.storage.local);
  }
});

function flushToSync() {
  // Be mindful of what gets synced: there are also size quotas
  // If needed, filter queuedChanges here

  // Generate a new sync stamp
  // With random instead of sequential, there's a really tiny chance
  //   changes will be ignored, but no chance of stamp overflow
  syncStamp = Math.random();
  queuedChanges._syncStamp = {newValue: syncStamp};

  // Process queue for committing
  commitChanges(queuedChanges, chrome.storage.sync);

  // Reset queue
  queuedChanges = {};
  timeout = undefined;
}

function commitChanges(changes, storage) {
  var setData = {};

  for(var key in changes) {
    setData[key] = changes[key].newValue;
  }

  storage.set(setData, function() {
    if(chrome.runtime.lastError) {
      console.error(chrome.runtime.lastError.message);
    }
  });
}

The idea here is to sync 3 seconds after the last change to local . 这里的想法是在最后一次更改为local后3秒进行同步。 Each new change is added to the queue and resets the countdown. 每个新更改都会添加到队列中,并重置倒数计时。 And while Chrome normally does not honor DOM timers in event pages, 3 seconds is short enough to complete before the page is shut down. 尽管Chrome通常不支持事件页面中的DOM计时器,但3分钟足以完成该页面的关闭。

Also, note that updating an area from this code will fire the event again. 另外,请注意,从此代码更新区域将再次触发该事件。 This is considered a bug (compare with window.onstorage not firing for changes within current document), but meanwhile I added the _syncStamp property. 这被认为是一个错误 (与window.onstorage相比,它不触发当前文档中的更改),但是与此同时,我添加了_syncStamp属性。 It is used to distinguish the local echo, though there is a tiny chance that the stamp will result in a collision 它用于区分局部回波,尽管印记有可能导致碰撞

Your other code (content script) should probably also rely on onChanged event instead of a custom "okay, I changed a value!" 您的其他代码(内容脚本)也应该依赖onChanged事件,而不是自定义“好,我更改了值!” message. 信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM