I'm writing a chrome extension that collects some data about the navigation (such as cookies, clicks, local storage changes...), and in the background script i'm writing the information to chrome.storage. I need to keep the data in the order it was caught.
I get the information from multiple listeners (1 listener for clicks in content script, 1 for cookies in background script, etc...). The data is written in an array, like this:
events: [
{
type:"click",
...
},
{
type:"cookie_change",
...
}
]
and every time i get a piece of information i read the array "events" and i write it all again. I want to point out that i don't want to change the data structure.
The problem is that sometimes i read multiple times before writing, and i am losing the data because i'm not doing R-W-R-W but R-R-W-W. So i thought i could implement something like a mutex. I've seen some solutions to similiar questions, but i found them a bit complicated and i didn't really understand them, so i wondered if there was an easier way and i tried this one:
var busy = false;
function tryWriteEvent(someData) {
if (busy)
setTimeout(() => { tryWriteEvent(someData); },100);
else {
busy = true;
writeEvent(someData);
}
}
function writeEvent(someData) {
chrome.storage.local.get(["events"], function(storage) {
...
chrome.storage.local.set({events:[...]});
busy = false;
});
}
It works, but i don't like putting the arbitrary limit of the setTimeout function. So i wondered if there was a solution with promises, something like this (that uses a queue of promises: the next writeEvent should be waiting for the previous one):
var promises = [];
function tryWriteEvent(someData) {
promises.push(writeEvent(someData, promises.length));
}
async function writeEvent(someData , position) {
if (position > 0)
await promises[position-1];
chrome.storage.local.get(["events"], function(storage) {
...
chrome.storage.local.set({events:[...]});
promises.shift();
return Promise.resolve();
});
}
This thing instead doesn't work, as the promise is not returned by writeEvent but by the function inside it. I have a bunch of questions:
- is there a way to "forward" the promise from the function inside 'chrome.storage.local.get' to 'writeEvent'?
- is there a way to make this work using promises? Or is there another more appropriate method?
Thanks in advance!