Javascript 如何将记录添加到chrome.storage.local而不重写其他写入操作

Javascript 如何将记录添加到chrome.storage.local而不重写其他写入操作,javascript,google-chrome-extension,callback,event-listener,google-chrome-storage,Javascript,Google Chrome Extension,Callback,Event Listener,Google Chrome Storage,我正在创建一个Chrome扩展,用于测量某些类型的选项卡活动。因此,我通过chrome.tabs创建了各种事件侦听器,用于侦听onReplaced、onUpdate、onCreated和其他事件 每个侦听器都需要存储数据,我正在使用存储API(chrome.Storage.local)来实现这一点。但是,存储API是基于回调的,正如它们在应用程序中定义的那样 发生的情况是,我在不同的事件侦听器中有多个对存储的调用,这些调用可能几乎同时触发。因此,对存储API有两个不同的get调用,然后是set调

我正在创建一个Chrome扩展,用于测量某些类型的选项卡活动。因此,我通过chrome.tabs创建了各种事件侦听器,用于侦听onReplaced、onUpdate、onCreated和其他事件

每个侦听器都需要存储数据,我正在使用存储API(chrome.Storage.local)来实现这一点。但是,存储API是基于回调的,正如它们在应用程序中定义的那样

发生的情况是,我在不同的事件侦听器中有多个对存储的调用,这些调用可能几乎同时触发。因此,对存储API有两个不同的
get
调用,然后是
set
调用来存储一些数据。两组数据都需要存储,但它们会相互覆盖,最后只存储一组数据

chrome.tabs.onCreated.addListener(onTabCreated);
chrome.tabs.onUpdated.addListener(onTabUpdated);

function onTabUpdated(tabId, changeInfo, tabAsUpdated) {
  var someRelevantData = // extract some data to be stored 
  chrome.storage.sync.get({'myKey' : {}}, function (data) { 
    var myDictionaryUpdated = data.myKey;
    myDictionaryUpdated ['newKey'] = someRelevantData;
    chrome.storage.sync.set({'myKey' : myDictionaryUpdated }, function() { 
      console.log("myKey updated --- new value is &s", JSON.stringify(myDictionaryUpdated, null, 4));
    });
  });
}

function onTabActivated(activeInfo) { 
  var someDifferentAndEquallyImportantData = // extract some data to be stored 
  chrome.storage.sync.get({'myKey' : {}}, function (data) { 
    var myDictionaryUpdated = data.myKey;
    myDictionaryUpdated['aSecondNewKey'] = someDifferentAndEquallyImportantData;
    chrome.storage.sync.set({'myKey' : myDictionaryUpdated }, function() { 
      console.log("myKey updated --- new value is &s", JSON.stringify(myDictionaryUpdated , null, 4));
    });
  });
}
onTabUpdated的回调返回使用“myKey”存储的对象,然后添加到该对象并在存储器中对其进行更新。但是,onTabActivated也会在“myKey”处获取对象(该对象仍然为空,因为来自上一个回调的set调用尚未运行),添加其自己的数据,然后将更新的对象写入存储器,覆盖onTabActivated回调中包含的任何数据


我找不到存储API的好文档,也找不到其他任何地方的答案-有关堆栈溢出的问题不涉及多个事件侦听器立即调用存储API。

这是任何异步存储的标准问题,不特定于扩展

解决方案1。使用同步
窗口。localStorage
。但它只能存储字符串,因此对于复杂数据,您需要JSON.stringify和JSON.parse。就性能而言,假设数据小于几千字节,则不会有任何差异,但如果有更多差异,则不要使用此方法

解决方案2。使用静默读/写函数,等待上一次调用完成:

const存储=(()=>{
让mutex=Promise.resolve();
const API=chrome.storage.sync;
常量mutexec=(方法,数据)=>{
互斥体=承诺.解析(互斥体)
.然后(()=>方法(数据))
。然后(结果=>{
互斥=空;
返回结果;
});
返回互斥;
};
const syncGet=data=>newpromise(resolve=>API.get(data,resolve));
const syncSet=data=>newpromise(resolve=>API.set(data,resolve));
返回{
读取:data=>mutexec(syncGet,data),
write:data=>mutexec(同步集,数据),
};
})();
用法:

异步函数示例(){
const{myKey}=wait storage.read({myKey:{});
myKey.foo='bar';
等待存储。写入({myKey});
}
解决方案3:使用存储键值对的变量将缓存添加到以前的解决方案中,但这是读者的练习(可能有现有的库/示例)

chrome.tabs.onCreated.addListener(onTabCreated);
chrome.tabs.onUpdated.addListener(onTabUpdated);

function onTabUpdated(tabId, changeInfo, tabAsUpdated) {
  var someRelevantData = // extract some data to be stored 
  chrome.storage.sync.get({'myKey' : {}}, function (data) { 
    var myDictionaryUpdated = data.myKey;
    myDictionaryUpdated ['newKey'] = someRelevantData;
    chrome.storage.sync.set({'myKey' : myDictionaryUpdated }, function() { 
      console.log("myKey updated --- new value is &s", JSON.stringify(myDictionaryUpdated, null, 4));
    });
  });
}

function onTabActivated(activeInfo) { 
  var someDifferentAndEquallyImportantData = // extract some data to be stored 
  chrome.storage.sync.get({'myKey' : {}}, function (data) { 
    var myDictionaryUpdated = data.myKey;
    myDictionaryUpdated['aSecondNewKey'] = someDifferentAndEquallyImportantData;
    chrome.storage.sync.set({'myKey' : myDictionaryUpdated }, function() { 
      console.log("myKey updated --- new value is &s", JSON.stringify(myDictionaryUpdated , null, 4));
    });
  });
}