2013-02-28 21 views
7

Eşzamansız bir yöntem beklemenin aptalca olduğunu biliyorum, one should use callbacks instead. Ancak, bir üçüncü taraf API'si sizi senkronize etmeye zorlarsa ne olur?Eşzamansız bir yöntemin geri dönüş değeri nasıl beklenir?

Kullanıcının başka bir sekmede açık olan web sitelerini ziyaret etmesini engelleyen bir Chrome Uzantısı geliştiriyorum. Temel olarak açık sekmelerdeki URL'lere dayalı istekleri iptal etmem gerekiyor. Böyle chrome.webRequest.onBeforeRequest kullanmak istiyorum:

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']); 

Umarım yukarıdaki kodda ikilemimi görüyoruz. Eşzamansız yöntem çağrılarının sonucuna göre bir nesne döndürmem gerekiyor. Bunu başarmak mümkün mü?

+1

Hayır, :-(değil – Bergi

+0

Tüm "chrome.tabs" değişikliklerini dinleyemiyor ve 'onBeforeRequest 'çağrıldığında zaten" websiteAlreadyOpenInOtherTab "değerini doğru olarak ayarlayamıyor musunuz? – Bergi

+0

Sorun yanlış. Öncelikle, eşzamansız olması gerekiyorsa, eşzamanlı bir yanıt gerektirmek yerine, model içinde çalışın ve sekmeye karar vermezseniz, kapatmanız gereken zaman uyumsuz bir geri çağırma kullanın. Sekmeleri kapatmak için ayrı bir API işlevi vardır, sadece ondan ön yüklemeden false döndürmeniz gerekmez ... – davin

cevap

6

Belki Eğer chrome.tabs.onUpdated ve chrome.tabs.onRemoved abone chrome.tabs.query

  • kullanarak uygulama başlatır

    1. , tüm açık sekme URL'leri almak sekmesi URL'lerin ?: takip ederek sorunu çözebilir ve değiştiğinde URL'leri ekleyin/kaldırın/güncelleyin. 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; 
          } 
          }; 
      
      }()); 
      

      Şimdi doğrudan tabUrlHandler sormak gerekir senin:

    documentation dayalı kod örneği çeşit

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

    Awesome! Çok ayrıntılı bir örnek için teşekkürler, bu benim almam gereken yol. – Sven

    +0

    Teşekkürler! İlginç bir soru için +1! :) – nekman

    İlgili konular