2013-02-28 3 views
7

나는 비동기 방법을 기다리는 것이 어리 석다는 것을 알고있다. one should use callbacks instead. 그러나 제 3 자 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']); 

이 희망 위의 코드에서 내 딜레마를 참조하십시오. 비동기 메서드 호출의 결과를 기반으로 개체를 반환해야합니다. 이것을 달성 할 수 있습니까?

+1

아니, :-(아니다 – Bergi

+0

'chrome.tabs'변경 사항을 모두 청취 할 수없고'onBeforeRequest'가 호출 될 때'websiteAlreadyOpenInOtherTab'에 이미 올바른 값이 들어 있습니까? – Bergi

+0

나는 당신이 접근하고 있다고 생각합니다. 문제를 잘못 처리하십시오. 첫째, 상황이 비동기 일 필요가 있다면 동기식 응답을 요구하는 대신 모델에서 작업하고 비동기식 콜백을 사용합니다. 탭을 열지 않아야한다고 결정하면 닫습니다. 탭을 닫는 별도의 API 함수가 있습니다. 단지 onbeforerequest에서 false를 반환 할 필요는 없습니다 ... – davin

답변

6

아마 당신은 chrome.tabs.onUpdatedchrome.tabs.onRemoved 구독 chrome.tabs.query

  • 를 사용하여 응용 프로그램이 시작

    1. 이 열려있는 모든 탭의 URL을 얻을 탭 URL을?을 추적하여 문제를 해결할 수 URL이 변경되면 추가/삭제/업데이트 할 수 있습니다. onBeforeRequestMethod

      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을 요청 할 수 있어야합니다 당신 :

    documentation에 따라 코드 예제의 일부 종류의

    function onBeforeRequest(details) { 
        var websiteAlreadyOpenInOtherTab = tabUrlHandler.contains(details.url); 
    
        if (websiteAlreadyOpenInOtherTab) { 
        return { cancel: true }; 
        } 
    } 
    
  • +0

    굉장! 아주 상세한 예를 들어 주셔서 감사합니다. 이것은 제가해야하는 길입니다. – Sven

    +0

    감사! 흥미로운 질문에 +1하세요! :) – nekman

    관련 문제