我想知道如何在Chrome扩展程序中以正确的方式处理本地存储和同步存储。
这是我的情况:
我正在为一个特定站点(目前)开发扩展,该站点
包含一个内容脚本和一个弹出窗口。
弹出窗口包含选项,用户可以在其中进行更改,然后将这些值发送到内容脚本以在页面上显示更改。
我希望尽可能减少保存和检索存储任务,最后将其保存在同步存储中,而不仅仅是保存在本地。
同步存储有每分钟的限制,而本地没有。
我知道如何使用长期连接从内容脚本监听弹出式关闭调用,并监听onConnect
和onDisconnect
,然后可以执行保存任务,但是有一种更好的方法来保存对存储的读写操作?
我所能想到的就是拥有一个后台脚本,我可以在其中存储变量中的更改,然后将它们发送到内容脚本和弹出窗口之间来回发送,因此就像有一个存储而不实际使用该存储一样,但是如何检测用户何时离开特定域,然后执行单个保存任务,以及关闭/停止后台/事件脚本?
当前chrome.storage.sync
持续运行的限制是每2秒1次(更准确的说是每小时1800次),并且突发速率限制为每分钟120次。
因此,您的工作是确保同步发生的频率不超过每2秒一次。
我将创建一个处理chrome.storage.onChanged
事件并同步两个区域的事件页面。由于局部回声,这是一项令人惊讶的艰巨任务!
// 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);
}
});
}
此处的想法是在最后一次更改为3秒后同步local
。每个新更改都会添加到队列中,并重置倒数计时。尽管Chrome通常不支持事件页面中的DOM计时器,但是3分钟足以完成该页面的关闭。
另外,请注意,从此代码更新区域将再次触发该事件。这被认为是一个错误(与window.onstorage
不触发当前文档中的更改相比),但是与此同时,我添加了该_syncStamp
属性。它用于区分局部回波,尽管印记极有可能导致碰撞
您的其他代码(内容脚本)也应该依赖于onChanged
事件,而不是自定义“好,我更改了值!” 信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句