Javascript 如何在唤醒事件页面时防止/检测处理和还原存储数据之间的竞争情况
我正在使用Javascript 如何在唤醒事件页面时防止/检测处理和还原存储数据之间的竞争情况,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我正在使用sendMessage和onMessage侦听器(在后台和内容页中),我看到一些消息丢失了。我有一些“全局”变量,每次进入挂起状态时都会存储这些变量,并在脚本启动时首先恢复它们(首先注册处理程序)。但是,考虑到chrome.storage是异步的,我怀疑在加载全局状态之前就已经进行了消息处理(因此出现了丢失消息的情况) 下面是相关的代码 # Register some important listeners. chrome.alarms.onAlarm.addListener(onAl
sendMessage
和onMessage
侦听器(在后台和内容页中),我看到一些消息丢失了。我有一些“全局”变量,每次进入挂起状态时都会存储这些变量,并在脚本启动时首先恢复它们(首先注册处理程序)。但是,考虑到chrome.storage
是异步的,我怀疑在加载全局状态之前就已经进行了消息处理(因此出现了丢失消息的情况)
下面是相关的代码
# Register some important listeners.
chrome.alarms.onAlarm.addListener(onAlarm);
chrome.runtime.onMessage.addListener(onMessage);
# Define global variables.
var tabIdList = new Array();
var keepAlives = new Array();
keepAlives["myTab1"] = -1;
keepAlives["myTab2"] = -1;
tabIdList["myTab1"] = -1;
tabIdList["myTab2"] = -1;
# Reload previously stored state of global variables...
reloadGlobalVariable();
# Handle received messages, anytime a message is received,
# set keepAlive for the tab that sends the message.
#
function onMessage(msg, sender) {
if (sender.tab) {
if (msg.message === "hello") {
recordNewTab(msg.tabName, sender.tab.id);
}
keepAlive(msg.tabName, sender.tab.id);
}
function recordNewTab(tabName, tabId) {
tabIdList[tabName] = tabId;
}
function keepAlive(tabName, tabId) {
if (tabIdList[tabName] == tabId) {
keepAlives[tabName] = 1;
}
}
chrome.runtime.onSuspend.addListener(function() {
storeGlobalState();
});
function onAlarm(alarm) {
for (var key in tabIdList) {
if (tabIdList[key] != -1) {
if (keepAlives[key] == -2) {
removeTabRecord(key);
} else {
--keepAlives[key];
sendMessage(key, "ping"); // content pages respond to this message
}
}
}
storeGlobalState(); // probably unnecessary.
}
如何确保只有重新加载全局变量后,onAlarm
才能继续处理
我使用异步的chrome.storage.local.set
/get
获取有关挂起/唤醒状态的调试提示的原始问题
好吧,对于事件页面处理和Chrome存储API的异步性质,您无能为力。异步JS中没有“延迟到” 因此,您需要处理回调。这应该起作用:
var globalsReady = false;
chrome.foo.onBar.addListener(handler);
function handler(a, b, c) {
restoreGlobals(function() {
/* Do actual handling using a, b, c */
});
// Special note for onMessage: if you are sending a reply asynchronously,
// you'll need to return true; here
}
function restoreGlobals(callback) {
if(!globalsReady) {
chrome.storage.local.get(/*...*/, function(data) {
/* restore globals here */
globalsReady = true;
if(typeof callback == "function") callback();
});
} else {
// Already done restoring
if(typeof callback == "function") callback();
}
}
restoreGlobals();
谢谢,这绝对是一个很好的解决方案。请您建议如何将变量号参数传递给restoreGlobals以传递回回调(因为不同的处理程序需要不同数量的回调变量)。嗯,为什么需要通过
restoreGlobals
传递它们?闭包将自动处理它-您可以在回调中引用处理程序
参数。(在中编辑)很酷,谢谢!我同时学习JS和chrome扩展开发。我正在阅读“经典”闭包讨论,在for循环中调用setTimeout来打印索引。错误地认为,我需要始终在函数调用时传递参数。谢谢你教我闭包规则。我强烈建议你仔细阅读你的答案。