2016-10-09 38 views
0

我的擴展正在修改一些URL。它工作正常,但現在我想檢查是否在設置中啓用修改或不。chrome ... addListener,如何等待chrome.storage.sync.get?

chrome.webRequest.onBeforeRequest.addListener 
(
    modifyUrl, 
    {urls: ['http://somewebsite/*'], types: ['main_frame']}, 
    ['blocking'] 
); 

問題是我不知道如何等待值。我必須在退出modifyUrl之前獲得設置。這可能嗎?如果這是C#,我可能會在調用sync.get之後使用ManualResetEvent或其他東西。

function modifyUrl(details) 
{ 
    chrome.storage.sync.get("someSetting", 
      function (data) 
      { 
      //I can get the setting here 
      } 
    ); 

    //how to know the setting here? 
    if(enabled in the setting) 
    { 
     return {redirectUrl: some different url}; 
    } 
} 
+0

看起來你需要一個回調或承諾等待異步操作,然後*然後*從函數返回 – adeneo

+0

這是一個想法 - > https://jsfiddle.net/adeneo/69pskkad/ – adeneo

+0

@adeneo如果在註冊事件偵聽器後設置更改? – qxz

回答

1

查看Returning Chrome storage API value without function的詳細解釋。

簡而言之,一個blocking onBeforeRequest事件是同步的,因此它不能依賴於異步函數,例如所有chrome。* API回調來派生它的返回值。

緩存全局變量中的數據,並在其他位置更改時使用chrome.storage.onChanged進行更新,如果您使用chrome.storage.sync(它在配置文件同步中更新),很容易發生。

var settingEnabled; // a global variable 
chrome.storage.sync.get("someSetting", function (data) { 
    var settingEnabled = data.someSetting; 
}); 

chrome.webRequest.onBeforeRequest.addListener(
    modifyUrl, 
    {urls: ['http://somewebsite/*'], types: ['main_frame']}, 
    ['blocking'] 
); 

function modifyUrl(details) { 
    if (settingEnabled) { 
     return {redirectUrl: 'http://example.com'}; 
    } 
} 

chrome.storage.onChanged.addListener(function(changes, area) { 
    if (area == "sync" && "someSetting" in changes) { 
     settingEnabled = changes.someSetting.newValue; 
    } 
}); 

當然,如果你想完全禁用處理,只需取下監聽器:

function toggleListener(enable) { 
    if (enable) { 
     chrome.webRequest.onBeforeRequest.addListener(
      modifyUrl, 
      {urls: ['http://somewebsite/*'], types: ['main_frame']}, 
      ['blocking'] 
     ); 
    } else { 
     chrome.webRequest.onBeforeRequest.removeListener(modifyUrl); 
    } 
} 

chrome.storage.onChanged.addListener(function(changes, area) { 
    if (area == "sync" && "someSetting" in changes) { 
     toggleListener(changes.someSetting.newValue); 
    } 
}); 

chrome.storage.sync.get("someSetting", function (data) { 
    toggleListener(data.someSetting); 
}); 

另一個有趣的方法是re-attach onBeforeRequest inside storage.get callback上的更新。