如何等待异步方法的回调返回值?
问题描述:
我知道等待异步方法很笨,one should use callbacks instead。但是如果第三方API迫使你同步呢?如何等待异步方法的回调返回值?
我正在开发一款Chrome扩展程序,可防止用户访问已在另一个选项卡中打开的网站。我基本上需要取消基于打开标签中的URL的请求。我想用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']);
希望你看到我的困境在上面的代码。我需要根据异步方法调用的结果返回一个对象。是否有可能实现这一目标?
答
解决问题
也许您可以通过跟踪标签的网址?:通过使用chrome.tabs.query
- 当应用程序启动后,得到所有打开的标签网址订阅
chrome.tabs.onUpdated
和chrome.tabs.onRemoved
并在更改时添加/删除/更新URL。
某种类型的代码示例的基础上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 };
}
}
不,这不是:-( – Bergi 2013-02-28 00:10:33
当你调用'onBeforeRequest'时,你不能听所有'chrome.tabs'的变化,并且'websiteAlreadyOpenInOtherTab'已经包含正确的值吗? – Bergi 2013-02-28 00:12:20
我觉得你很亲切不正确地解决问题。首先,如果事情需要是异步的,那么不需要同步响应,而是在模型中工作,并使用异步回调,如果您决定选项卡不应该打开,则关闭它。有一个单独的API函数来关闭标签,你不需要仅仅从onbeforerequest返回false ... – davin 2013-02-28 00:23:31