以逐步方式同步处理URL的列表?

时间:2014-01-18 19:16:19

标签: javascript google-chrome-extension

我们有一些网址列表:

var urls = ['http://google.com','http://yahoo.com','http://yandex.com'];

我们的任务是遍历此URL列表并...

  • 为网址创建,请记住tabId
  • 使用chrome.webRequest.onCompleted过滤器
  • 将监听器附加到tabId
  • 在上次chrome.webRequest.onCompleted甚至发生后
  • 等待3秒钟
  • 分离听众
  • 继续下一个网址

我需要在成功处理上一个URL后才处理每个下一个URL。我不需要并行运行它们。

这是将并行运行的代码。如何将其修改为以同步方式逐个运行?

var processURL = function(url) {

    //var that contains timestamp of last chrome.webRequest.onCompleted event
    var lastOnCompletedTimestamp = null;

    //our listeners that will be attached
    var webRequestListeners = {
        onCompleted : function(details) {
            lastOnCompletedTimestamp = new Date().getTime();
        }
    }   

    //method to attach web request listener
    var attachWebRequestListeners = function(tabId) {
        chrome.webRequest.onCompleted.addListener(
            webRequestListeners.onCompleted,
            {urls: [ "<all_urls>" ], types : ["main_frame"], tabId : tabId},
            ['responseHeaders']         
        )
    }

    //method to detach web request listener
    var detachWebRequestListeners = function(tabId) {
        //Attention: I'm not sure is it possible to detach webRequest listeners 
        //for tabId; I was unable to find any description for that at Chrome Extension API docs
    }

    //method 
    var onTabCreated = function(tab) {
        var tabId = tab.tabId;
        attachWebRequestListeners(tabId);
        //when all webRequest listeners are attached we can update tab to go to URL
        chrome.tabs.update(tabId, {url:url});
        var interval = setInterval(function() {
            if (
                lastOnCompletedTimestamp != null 
                && new (Date().getTime() - lastOnCompletedTimestamp < 3000)
            ) {
                //if more that 3 sencods past from last onCompleted event - detach events
                detachWebRequestListeners(tabId);
                            clearInterval(interval);

            }
        }, 200);
    }

    //creating empty tab without URL
    chrome.tabs.create(
        {active: false},
        function(tab) {
            onTabCreated(tab);
        }
    );

}

var urls = ['http://www.google.com', 'http://yandex.ru', 'http://.yahoo.com'];
for(var i in urls) {
    //this will start all urls in parallel, but I need to wait for execution of one url and only after this go to next one
    processURL(urls[i]);
}

UPD:我找到了非常好的Deferred js对象(请参阅http://cho45.stfuawsc.com/jsdeferred/#behavior)它允许使用loopnext循环访问网址,但是我们必须做一些修改,参见Deferred tuts。

1 个答案:

答案 0 :(得分:1)

只有在完成上一个选项卡的处理后,才需要开始处理每个选项卡。这可以通过在上一个选项卡的间隔回调结束时启动标签处理来实现:

更改您的代码:

var urls = [...];
var processURL = function (idx) {
    if (idx >= urls.length) { return; }
    var url = urls[idx];
    ...
    var onTabCreated = function(tab) {
        ...
        var interval = setInterval(function() {
            ...
            clearInterval(interval);
            processURL(idx + 1);
    ...
};
processURL(0);

BTW,tabId = tab.tabId should be tabId = tab.id