我知道等待异步方法很愚蠢,one should use callbacks instead。但是如果第三方API强迫你同步呢?
我正在开发一个Chrome扩展程序,可防止用户访问已在另一个标签页中打开的网站。我基本上需要根据打开标签中的网址取消请求。我想像这样使用chrome.webRequest.onBeforeRequest
:
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab;
// Here i want to set `websiteAlreadyOpenInOtherTab` by using the `chrome.tabs`
// API. It's asynchronous though and that's my problem. I cant return a value
// from an asynchronous method call.
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}
chrome.webRequest.onBeforeRequest.addListener(
onBeforeRequest,
{ urls: ['<all_urls>'], types: ['main_frame'] },
['blocking']);
希望您在上面的代码中看到我的困境。我需要根据异步方法调用的结果返回一个对象。是否有可能实现这一目标?
答案 0 :(得分:6)
也许 您可以通过跟踪标签网址来解决问题?:
chrome.tabs.query
chrome.tabs.onUpdated
和chrome.tabs.onRemoved
,并在网址发生变化时添加/删除/更新。某种基于documentation的代码示例:
var tabUrlHandler = (function() {
// All opened urls
var urls = {},
queryTabsCallback = function(allTabs) {
allTabs && allTabs.forEach(function(tab) {
urls[tab.id] = tab.url;
});
},
updateTabCallback = function(tabId, changeinfo, tab) {
urls[tabId] = tab.url;
},
removeTabCallback = function(tabId, removeinfo) {
delete urls[tabId];
};
// init
chrome.tabs.query({ active: true }, queryTabsCallback);
chrome.tabs.onUpdated.addListener(updateTabCallback);
chrome.tabs.onRemoved.addListener(removeTabCallback);
return {
contains: function(url) {
for (var urlId in urls) {
if (urls[urlId] == url) {
return true;
}
}
return false;
}
};
}());
现在,您应该可以直接在tabUrlHandler
:
onBeforeRequestMethod
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab = tabUrlHandler.contains(details.url);
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}