如何等待异步方法的回调返回值?

Sve*_*ven 7 javascript asynchronous google-chrome-extension

我知道等待异步方法是愚蠢的,应该使用回调.但是如果第三方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']);
Run Code Online (Sandbox Code Playgroud)

希望你在上面的代码中看到我的困境.我需要根据异步方法调用的结果返回一个对象.是否有可能实现这一目标?

nek*_*man 6

也许您可以通过跟踪选项卡URL来解决问题?:

  1. 应用启动时,请使用以获取所有打开的标签网址 chrome.tabs.query
  2. 订阅chrome.tabs.onUpdatedchrome.tabs.onRemoved在更改时添加/删除/更新URL.

基于文档的某种代码示例:

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;
     }
   };

}());
Run Code Online (Sandbox Code Playgroud)

现在你应该可以tabUrlHandler直接问你onBeforeRequestMethod:

function onBeforeRequest(details) {
  var websiteAlreadyOpenInOtherTab = tabUrlHandler.contains(details.url);

  if (websiteAlreadyOpenInOtherTab) {
    return { cancel: true };
  }
}
Run Code Online (Sandbox Code Playgroud)