管理Chrome扩展中存储的变量

huangapple go评论49阅读模式
英文:

manage stored variables in Chrome extendion

问题

我正在尝试掌握管理跨我的第一个Chrome扩展中要使用的持久变量的方法。如果我理解正确,正确的方式是使用存储(在我的情况下,我使用的是storage.local)。

在我的background.js脚本中,我设置了以下代码,其中包括3个函数来初始化一个变量(设置为0),更新它(每次调用updateApiCalls()函数时将其增加1),以及将它打印到控制台以检查过程是否有效:

const resetApiCalls = () => {
    chrome.storage.local.set({"apiCalls": 0});
};

const updateApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        chrome.storage.local.set({"apiCalls": items.apiCalls + 1});
    });
};

const printApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        console.log("apicalls: " + items.apiCalls);
    });
};

resetApiCalls();
updateApiCalls();
printApiCalls();

结果是printApiCalls()仍然将0记录到控制台,就好像变量没有被updateApiCalls()改变一样。

在我的代码中我做错了什么?
还是我完全偏离了轨道,应该使用完全不同的方法来执行这个任务?

英文:

I am trying to get the hang of managing persistent variables to be used across my first chrome extension. If I get it correctly the proper way is to use storage (i am using storage.local in my case).

In my background.js script I set up the code as below, with 3 functions to initialize a variable (to 0), update it (by increasing it by 1 everytime the updateApiCalls() function is called) and to print it console to check if the process worked:

const resetApiCalls = () => {
    chrome.storage.local.set({"apiCalls": 0})
};

const updateApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        chrome.storage.local.set({"apiCalls": items.apiCalls + 1})
    });
};

const printApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        console.log("apicalls:  " + items.apiCalls);
    }); 
};

resetApiCalls();
updateApiCalls();
printApiCalls();

The result is that the printApicalls() still logs 0 to console as if the variable didn't get changed by updateApiCalls().

What I am doing wrong in my code?
Or am I completely off track and should use a completely different approach to perform this task?

答案1

得分: 2

const resetApiCalls = () => {
    return new Promise((resolve) => {
        chrome.storage.local.set({ "apiCalls": 0 }, () => {
            resolve();
        });
    });
};

const updateApiCalls = () => {
    return new Promise((resolve) => {
        chrome.storage.local.get(["apiCalls"], async (items) => {
            await chrome.storage.local.set({ "apiCalls": items.apiCalls + 1 }, () => {
                resolve();
            });
        });
    });
};

const printApiCalls = () => {
    return new Promise((resolve) => {
        chrome.storage.local.get(["apiCalls"], (items) => {
            console.log("apicalls: " + items.apiCalls);
            resolve();
        });
    });
};

(async () => {
    await resetApiCalls();
    await updateApiCalls();
    await printApiCalls();
})();
/*
//you can also write this way
resetApiCalls().then(() => updateApiCalls()).then(() => printApiCalls());
*/
英文:
    const resetApiCalls = () => {
        return chrome.storage.local.set({"apiCalls": 0})
    };
    
    const updateApiCalls = async () => {
        var items = await chrome.storage.local.get(["apiCalls"]);
        return chrome.storage.local.set({"apiCalls": items.apiCalls + 1})
    };
    
    const printApiCalls = () => {
        chrome.storage.local.get(["apiCalls"]).then((items) => {
            console.log("apicalls:  " + items.apiCalls);
        }); 
    };
    
    (async _ => {
       await resetApiCalls();
       await updateApiCalls();
       printApiCalls();
    })()
    /*
    //you can also write this way
    resetApiCalls().then(updateApiCalls).then(printApiCalls);
    */

The 3 functions are asynchronous so you have to find a way to execute them one after the other synchronously otherwise the result is unpredictable.
I transformed the first 2 functions so that they returned a promise after which I waited for each of these promises to be fullfilled to execute the next function.

答案2

得分: 1

在表面上,您正在做一切正确。

但是,对于 Chrome 存储有一个需要注意的地方...来自他们的 API 的引用。

存储和限制

不要认为将内容添加到存储 API 就像将东西放入一辆大卡车中。将内容添加到存储中就像将东西放入管道中。这个管道可能已经有材料,甚至可能已经填满了。始终假设在将内容添加到存储中和实际记录之间存在延迟。

两个具有工作结果的示例。

  1. 使用 async/await
const resetApiCalls = async () => {
    await chrome.storage.local.set({"apiCalls": 0})
};

const updateApiCalls = async () => {
    const result = await chrome.storage.local.get(["apiCalls"]);
    const incremented = result.apiCalls + 1;
    await chrome.storage.local.set({"apiCalls": incremented})
};

const printApiCalls = async () => {
    const result = await chrome.storage.local.get(["apiCalls"]);
    console.log("result: ", result);
};

(async function () {
    await resetApiCalls();
    await updateApiCalls();
    await printApiCalls(); //控制台打印 { "apiCalls": 1 }
})();
  1. 使用 setTimeout 作为对您的代码的测试。
const resetApiCalls = () => {
    chrome.storage.local.set({"apiCalls": 0})
};

const updateApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        chrome.storage.local.set({"apiCalls": items.apiCalls + 1})
    });
};

const printApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        console.log("apicalls: " + items.apiCalls);
    });
};

resetApiCalls();
updateApiCalls();
// printApiCalls();
setTimeout(function() {
    printApiCalls(); //控制台打印 "apicalls:  1"
}, 5000);

希望这解决了问题。

英文:

On the surface you're doing everything correctly.

However there is a caveat with chrome storage... quote from their api.

> ## Storage and throttling limits ##
> Don't think of adding to the Storage API as putting things in a big truck. Think of adding to storage as being like putting something in a pipe. The pipe may have material in it already, and it may even be filled. Always assume a delay between when you add to storage and when it is actually recorded.

Two examples with working results.

  1. Using async/await
const resetApiCalls = async () => {
    await chrome.storage.local.set({"apiCalls": 0})
};

const updateApiCalls = async () => {
    const result = await chrome.storage.local.get(["apiCalls"]);
    const incremented = result.apiCalls + 1;
    await chrome.storage.local.set({"apiCalls": incremented})
};

const printApiCalls = async () => {
    const result = await chrome.storage.local.get(["apiCalls"]);
    console.log("result: ", result);
};

(async function () {
    await resetApiCalls();
    await updateApiCalls();
    await printApiCalls(); //console.log prints {"apiCalls": 1}
})();
  1. using a setTimeout as a test with your code.
const resetApiCalls = () => {
    chrome.storage.local.set({"apiCalls": 0})
};

const updateApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        chrome.storage.local.set({"apiCalls": items.apiCalls + 1})
    });
};

const printApiCalls = () => {
    chrome.storage.local.get(["apiCalls"]).then((items) => {
        console.log("apicalls:  " + items.apiCalls);
    });
};

resetApiCalls();
updateApiCalls();
// printApiCalls();
setTimeout(function() {
    printApiCalls(); //console.log prints "apicalls:  1"
}, 5000);

Hope this clears up the issue.

huangapple
  • 本文由 发表于 2023年2月18日 19:36:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493060.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定