英文:
Making sure settings are set before executing other logic in Chrome v3 extension
问题
这是一个 background.js 文件的示例,属于一个 v3 版本的 Chrome 扩展。我尝试在安装期间设置扩展的默认设置。
const settings = {
enableContextMenu: true,
};
chrome.runtime.onInstalled.addListener(details => {
if (details.reason === 'install') {
chrome.storage.local.set(settings);
}
});
chrome.storage.local
.get(['enableContextMenu'])
.then(({ enableContextMenu }) => {
// 此处 enableContextMenu 未定义
if (enableContextMenu) {
chrome.contextMenus.create({
id: 'extension-contextmenu',
title: 'Extension Menu',
type: 'normal',
contexts: ['link'],
});
}
});
但是,我如何知道设置已在 onInstalled 中设置,以便我可以继续通过检查存储中的 enableContextMenu 添加上下文菜单?在这个示例中,尽管设置应该在 onInstalled 监听器中设置,但获取 enableContextMenu 时返回 未定义,可能是由于竞态条件引起的。
正确的算法是如何初始化设置并根据设置执行其他逻辑的?
英文:
This is an example background.js of a v3 chrome extension. I try to set the default settings of the extension during installation.
const settings = {
enableContextMenu: true,
};
chrome.runtime.onInstalled.addListener(details => {
if (details.reason === 'install') {
chrome.storage.local.set(settings);
}
});
chrome.storage.local
.get(['enableContextMenu'])
.then(({ enableContextMenu }) => {
// enableContextMenu is undefined here
if (enableContextMenu) {
chrome.contextMenus.create({
id: 'extension-contextmenu',
title: 'Extension Menu',
type: 'normal',
contexts: ['link'],
});
}
});
But how do I know the settings are set in onInstalled already so that I can continue adding a context menu by checking the enableContextMenu from storage? In this example, getting enableContextMenu is undefined although settings were supposed to be set in onInstalled listener, probably because of race condition.
What is the correct algorithm to initialize settings and execute other logic depending on settings?
答案1
得分: 1
不要回答我要翻译的问题。以下是要翻译的内容:
"这个想法总体上并不错,但我仍然建议在你不确定对象是否已初始化时使用这种语法。
对于用户触发的事件(我指的是像action.on*、omnibox.on*、command.on*等chrome API),通常不需要这种技巧,因为当它们触发时,你可以相当确定参数已经初始化了。
不同的是其他事件,如“runtime.onMessage”和“runtime.onInstalled”,它们的激活不总是可以事先预见的,因此很难确定代码执行流程。
当然,首次“通过”时,首先执行主流程的指令,包括同步和异步的指令,然后转到任何回调函数,最后执行chrome事件(至少我是这样知道的)。
因此,在onInstalled中设置初始参数是可以的,因为你可以确保它们不会被第二次重新初始化(这可能会有害),但请注意,onInstalled事件处理程序肯定不会首先运行。"
英文:
It's not a bad idea in general, but I still recommend using this syntax when you're not sure if the object has been initialized.
For user triggered events (I'm referring to chrome APIs like action.on*, omnibox.on*, command.on* etc) normally there is no need for this trick because when they fire you can be pretty sure that the parameters initialization is passed.
Different for other events such as "runtime.onMessage" and "runtime.onInstalled" whose activation is not always foreseeable in advance and therefore it is not easy to establish the code execution flow in general.
Certainly with the first "pass" the instructions of the main flow are executed first, both the synchronous and the asynchronous ones, after which it passes to any callback functions and lastly the chrome events are honored (at least I know it like this).
It's OK then to set the initial parameters to onInstalled because you're sure they won't be reinitialized a second time (which could be deleterious), but be aware that the onInstalled event handler certainly does NOT run first.
答案2
得分: 0
请尝试这个。
const settings = {
enableContextMenu: true,
};
const main = async () => {
const result = await chrome.storage.local.get("enableContextMenu");
console.log(result.enableContextMenu);
if (!result.enableContextMenu) {
chrome.storage.local.set(settings);
}
}
main();
英文:
Please try this.
const settings = {
enableContextMenu: true,
};
const main = async () => {
const result = await chrome.storage.local.get("enableContextMenu");
console.log(result.enableContextMenu);
if (!result.enableContextMenu) {
chrome.storage.local.set(settings);
}
}
main();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论