Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在唤醒事件页面时防止/检测处理和还原存储数据之间的竞争情况_Javascript_Google Chrome Extension - Fatal编程技术网

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来打印索引。错误地认为,我需要始终在函数调用时传递参数。谢谢你教我闭包规则。我强烈建议你仔细阅读你的答案。